Introduction

Understanding the relationship between happiness and commuting is a significant area of interest in social science research. Commuting, defined as the daily travel time to and from work, is an integral part of many individuals’ lives, particularly in urban settings. Previous studies have highlighted that commuting time can impact various dimensions of well-being, including physical health, mental health, and overall life satisfaction. As cities grow and commuting times lengthen, investigating how commuting affects happiness becomes increasingly relevant.

SOEP data

The Socio-Economic Panel (SOEP) is a longitudinal survey that has been conducted annually since 1984 by the German Institute for Economic Research (DIW Berlin). It provides a rich, multi-dimensional dataset that includes detailed information on households and individuals in Germany, covering aspects such as income, employment, education, health, and life satisfaction. The SOEP is one of the largest and most comprehensive panel datasets available, allowing researchers to analyze the dynamic aspects of socio-economic conditions and behaviors over time. It is a valuable resource for studying trends and patterns within the German population, providing insights into how economic, social, and personal factors interact to shape individuals’ lives and societal outcomes.

Definition of Key Terms

In this study, Happiness is defined as the self-reported life satisfaction score, as measured in the Socio-Economic Panel (SOEP) dataset. Commuting refers to the total time an individual spends traveling from home to work and back, typically measured in minutes per day. Life satisfaction is a subjective assessment of one’s overall well-being and contentment with life. Life satisfaction was chosen as the measure of happiness because no other more suitable variables were available in the data sets accessible to us to describe the level of happiness.

Literature Review

The existing literature indicates that commuting has significant implications for an individual’s subjective well-being, with various studies revealing both direct and indirect effects on happiness. Stutzer and Frey (Stutzer & Frey, 2008) describe the “commuting paradox,” where longer commuting times, despite potential financial or employment benefits, are consistently linked to lower levels of life satisfaction. This paradox underscores the psychological stress and reduced time for personal and social activities that longer commutes often entail. Kahneman et al. (Kahneman et al., 2004) further emphasize the negative impact of commuting on daily well-being by using the Day Reconstruction Method (DRM) to categorize commuting as one of the least enjoyable daily activities. Their research shows that commuting significantly contributes to daily stress and overall dissatisfaction with life, underscoring its role in shaping daily experiences.

Meier and Stutzer (Meier & Stutzer, 2008) contribute to this discussion by exploring the broader context of time use and its influence on happiness. Although their study primarily investigates the benefits of volunteering, they note that time spent commuting can reduce opportunities for engaging in fulfilling activities, such as socializing or volunteering, which are crucial for maintaining happiness. This aligns with findings from Petrunoff et al. (Petrunoff et al., 2017), who highlight the benefits of active commuting modes, such as walking or cycling, particularly in work settings. Their systematic review suggests that interventions encouraging active commuting can mitigate some of the negative impacts associated with longer or more stressful commutes, thus enhancing overall life satisfaction and reducing stress levels.

Clark et al. (Clark et al., 2019) delve deeper into the nuances of how different commuting modes affect subjective well-being. They found that individuals commuting by car tend to report lower happiness levels compared to those who walk or cycle, potentially due to the associated physical activity and exposure to more pleasant environments. Moreover, the study underscores the importance of perceived control over one’s commuting method in influencing its impact on life satisfaction. This suggests that the ability to choose one’s mode of transport, and thereby potentially reduce commute-related stress, plays a significant role in determining the overall well-being of commuters.

Despite the extensive body of research on commuting and happiness, there remains a gap in understanding how various socio-economic and demographic factors, such as income, employment status, and geographic region, interact with commuting to affect happiness levels.

Data sets and Variables

We had access to six datasets: gripstr.dta, hgen.dta, hl.dta, pequiv.dta, pgen.dta, and pl.dta. After thoroughly examining each dataset, I selected four that contained the necessary information for my analysis: hgen.dta, pequiv.dta, pgen.dta, and pl.dta. The datasets gripstr.dta and hl.dta were not included in the final analysis, as they did not contain the relevant variables for my research.

The chosen datasets provided comprehensive data on employment status, household characteristics, life satisfaction, and educational background, which were crucial for understanding the relationships between life satisfaction and commuting behavior. However, it’s important to note that some variables were not available due to restricted access. For instance, the residence information variable (l11101) in the pequiv.dta was inaccessible, which limited the analysis of certain aspects related to geographic and residential factors.

Variables included:

  1. Age

  2. Gender

  3. Marital Status

  4. Number of persons in household

  5. Number of years of education

  6. Education with respect to High School

  7. Household income satisfaction

  8. Commuting distance

  9. Commuting Frequency

  10. Commuting Time (Minutes)

  11. Monthly household income

  12. Employment Status

Each variable in the datasets is available for different time periods. Some cover the whole duration of the SOEP study, from 1984 to 2020, while others are only available for specific years. As a result, I used the primary variables for the entire study period, but some detailed indicators are only available for shorter times.

To handle the large amount of data, I also shortened the research period for some analyses. This made the data more manageable and helped focus on specific aspects of the study.

Overall, this approach allowed me to analyze life satisfaction and commuting behavior in a clear and organized way, despite the challenges with data availability and size.

Hypotheses

Based on the literature review, I hypothesize that longer commuting times are associated with lower levels of happiness. Additionally, I claim that this relationship may vary depending on socio-economic factors such as income, employment status, and education.

Demographics Analysis

To begin, we will examine the key demographic variables of SOEP data: age, gender, and marital status. All of these variables are contained in the pequiv.dta database. These demographic factors are crucial as they provide foundational context for understanding the characteristics of the population under study. Analyzing these variables will help us identify patterns and correlations that may influence other aspects of the study, such as happiness and commuting time. Understanding the distribution and characteristics of these demographics allows us to better interpret the broader social and economic dynamics at play.

Average Age by Year

Age Distribution by Year

This box plot effectively illustrates the distribution of the ages of respondents from 1984 to 2020. It provides a clear view of the minimum and maximum ages for each year, allowing for an easy identification of the age range over time. Additionally, the plot highlights the median age and showcases the variability in ages across different years.

pequiv_dem <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11101", "d11102ll", "d11104"))


pequiv_dem_filter <- pequiv_dem %>%
  rename(
    `age` = d11101,
    `gender` = d11102ll,
    `marital status` = d11104
  )

pequiv_dem_filter <- pequiv_dem_filter %>%
  mutate(age = as.numeric(age)) %>%
  filter(age > 0)

# Age Distribution
ggplot(pequiv_dem_filter, aes(x = as.factor(syear), y = age)) + 
  geom_boxplot(fill = "mediumseagreen", color = "black") +
  labs(title = "Age Distribution by Year", x = "Year", y = "Age") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5))  

Average Age by Year

The graph shows fluctuations in the average age over the years. The line illustrates the general direction or trend of the average age, whether it is increasing, decreasing, or remaining stable.

average_age_by_year <- pequiv_dem_filter %>%
  group_by(syear) %>%
  summarize(average_age = mean(age, na.rm = TRUE))

ggplot(average_age_by_year, aes(x = syear, y = average_age)) + 
  geom_line(color = "tomato", linewidth = 0.2) +  
  geom_point(color = "tomato", size = 2) +   
  labs(title = "Average Age by Year", x = "Year", y = "Average Age") +
  theme_minimal()

Starting from 1990, the plot reveals a gradual increase in the mean age of respondents up until nearly the end of the 2010s. Notably, there is a significant drop in median age in 2010 compared to 2009, with the median age falling from approximately 42 to 35. Following this sharp decline, the median age has not risen above 36 in subsequent years, indicating a sustained trend of younger respondents in the more recent data. This shift may reflect broader demographic changes or shifts in the survey population over time.

Gender Distribution

The histogram illustrates the gender distribution over time from 1984 to 2020.

  • The gender proportions exhibit fluctuations over the years, with noticeable variations in the ratio of males to females across different periods.
  • Significant shifts can be seen at certain points in time, such as the early 1990s and around 2000, reflecting changes in gender representation within the dataset.
  • Recent years show a more balanced gender distribution, with proportions converging towards equal representation.
pequiv_dem_filter <- pequiv_dem_filter %>%
  mutate(gender = as.numeric(gender),
         syear = as.numeric(syear)) %>%
  filter(gender > 0)

pequiv_dem_filter <- pequiv_dem_filter %>%
  mutate(gender = factor(gender, levels = c(1, 2), labels = c("Male", "Female")))

gender_proportion_by_year <- pequiv_dem_filter %>%
  group_by(syear, gender) %>%
  summarise(count = n(), .groups = 'drop') %>%
  group_by(syear) %>%
  mutate(total = sum(count),
         proportion = count / total * 100)

ggplot(gender_proportion_by_year, aes(x = syear, y = proportion, color = gender, group = gender)) + 
  geom_line(linewidth = 0.2) +
  geom_point(size = 2) +
  labs(title = "Gender Distribution Over Time", x = "Year", y = "Proportion (%)") +
  scale_color_manual(values = c("Male" = "skyblue", "Female" = "salmon"),
                     name = "Gender") + 
  theme_minimal()

Marital Status Distribution

The bar plot shows the distribution of marital statuses across different years. Each color represents a different year, and the height of the bars represents the proportion of respondents in each marital status category.

  • The majority of respondents are married, with a consistent proportion of over 60% across the years.
  • The proportion of single individuals is the second highest, followed by widowed, divorced, and separated individuals.
  • We can also observe that since the mid-2000s, the popularity of divorces has increased, while the number of marriages has significantly declined.
  • Similarly, the number of single individuals began to rise sharply around 2010.

These trends may point to evolving cultural, social, and economic factors influencing people’s choices regarding marriage and relationships.

pequiv_dem_filter <- pequiv_dem_filter %>%
  filter(`marital status` > 0) %>%  
  mutate(`marital status` = factor(`marital status`,  
                                   levels = 1:5, 
                                   labels = c("Married", "Single", "Widowed", "Divorced", "Separated")))

stats_by_year_marital_status <- pequiv_dem_filter %>%
  group_by(syear, `marital status`) %>%
  summarise(count = n(), .groups = 'drop')



stats_by_year_marital_status <- stats_by_year_marital_status %>%
  group_by(syear) %>%
  mutate(total = sum(count),
         proportion = count / total * 100)

ggplot(stats_by_year_marital_status, aes(x = `marital status`, y = proportion, fill = factor(syear))) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Marital Status Distribution by Year (Proportion)", x = "Marital Status", y = "Proportion (%)", fill = "Year") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.text = element_text(size = 6),  
        legend.title = element_text(size = 6))

Household and individual income

I analyzed household income data to explore how average monthly household income varies with the number of household members and how income per person in a household changes over the years. These analyses provide insights into income distribution patterns and their potential impact on commuting behaviors and overall happiness.

Average monthly household income

Here I wanted to merge and clean household income and size data, then visualize how average monthly household income varies with the number of household members across the years. But the data was so vast and there there more than 1 million variables. So I decided to choose only years from 2018 to 2020. The plot helps to identify trends and patterns in income distribution relative to household size during these years. The facet wrap allows for a comparative view of income trends across the specified years, helping to identify any significant changes or consistent patterns.

Main observations:

The analysis of the average monthly household income in relation to the number of household members from 2018 to 2020 reveals several interesting trends. The data shows that household income increases as the number of family members grows, but this trend only holds up to a certain point. Specifically, the average income rises steadily with household size until it reaches five members. Beyond this threshold, the income begins to decline gradually, suggesting that additional family members may lead to diminishing financial returns, possibly due to increased living costs or resource allocation challenges.

However, the trend takes a surprising turn when the number of household members exceeds nine. At this point, there is a sharp increase in average household income, which could indicate the presence of additional income earners in larger households or economies of scale that benefit very large families. Following this unexpected spike, the income drops sharply again, highlighting potential volatility and financial strain in extremely large households.

These findings suggest that while larger households may benefit from multiple income sources, they also face increased financial pressures that can impact their overall economic stability.

#1
hgen_hhinc_data <- read_dta("C:\\R\\final project\\data\\hgen.dta", col_select = c("cid", "hid", "syear", "hghinc"))

hgen_hhinc_data <- hgen_hhinc_data %>%
  rename(
    `monthly_hhinc` = hghinc
  )
#2
pl_hhinc_data <- read_dta("C:\\R\\final project\\data\\pl.dta", col_select = c("cid", "hid", "pid", "syear", "plh0175"))

pl_hhinc_data <- pl_hhinc_data %>%
  rename(
    `hhinc_sat` = plh0175
  )
#3
pequiv_hhsize_data <- read_dta("C:\\R\\final project\\data\\pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11106"))

pequiv_hhsize_data <- pequiv_hhsize_data %>%
  rename(
    `hh_size` = d11106,
  )

pl_hgen_pequiv_hhinc <- full_join(hgen_hhinc_data, pl_hhinc_data, by = c("hid", "syear"))
pl_hgen_pequiv_hhinc <- full_join(pl_hgen_pequiv_hhinc, pequiv_hhsize_data, by = c("hid", "syear"))

pl_hgen_pequiv_hhinc <- pl_hgen_pequiv_hhinc %>%
  mutate(across(everything(), ~ as.numeric(as.character(.))))

pl_hgen_pequiv_hhinc <- na.omit(pl_hgen_pequiv_hhinc)

pl_hgen_pequiv_hhinc_filter <- pl_hgen_pequiv_hhinc %>% filter(hhinc_sat >= 0, monthly_hhinc >= 0, hh_size >= 0) 

pl_hgen_pequiv_hhinc_18_20 <- pl_hgen_pequiv_hhinc_filter %>% filter(syear <= 2020 & syear >= 2018)

ggplot(pl_hgen_pequiv_hhinc_18_20, aes(x = hh_size, y = monthly_hhinc)) +
  stat_summary(fun = "mean", geom = "line", color = "cornflowerblue") +  
  stat_summary(fun = "mean", geom = "point", color = "cornflowerblue") +   
  labs(title = "Average monthly household income depending on the number of family members",
       x = "Number of HH members",
       y = "Mean monthly income of HH (EUR)") +
  facet_wrap(~ syear) + 
  theme_minimal()

Average Income Per Person in household

To further analyze household income dynamics, I calculated the income per household member to understand the average income per individual in each household. This calculation was necessary because the available dataset did not provide a variable for monthly individual income. By deriving this metric, I could more accurately assess the financial situation on a per-person basis within households.

Main observations:

The resulting plot displays the trend of average income per person from 2018 to 2020. The graph shows a gradual increase in the average income per person over the years, indicating an overall improvement in individual economic conditions within households. This upward trend suggests that household incomes are rising in a way that benefits each member more significantly over time.

A particularly notable observation from the graph is the marked increase in per capita income in 2001. This significant jump may reflect broader economic changes, policy impacts, or shifts in the labor market that particularly benefitted households during that year.

#1
hgen_hhinc_data <- read_dta("C:/R/final project/data/hgen.dta", col_select = c("cid", "hid", "syear", "hghinc"))

hgen_hhinc_data <- hgen_hhinc_data %>%
  rename(
    `monthly_hhinc` = hghinc
  )

#2
pequiv_hhsize_data <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11106"))

pequiv_hhsize_data <- pequiv_hhsize_data %>%
  rename(
    `hh_size` = d11106
  )
hgen_pequiv_hhinc <- full_join(hgen_hhinc_data, pequiv_hhsize_data, by = c("hid", "syear"))


hgen_pequiv_hhinc <- hgen_pequiv_hhinc %>%
  mutate(across(everything(), ~ as.numeric(as.character(.))))

hgen_pequiv_hhinc <- na.omit(hgen_pequiv_hhinc)

hgen_pequiv_hhinc_filter <- hgen_pequiv_hhinc %>% filter( monthly_hhinc >= 0, hh_size >= 0) 

hgen_pequiv_hhinc_filter <- hgen_pequiv_hhinc_filter %>%
  mutate(
    income_per_person = monthly_hhinc / hh_size
  )


income_per_person_by_year <- hgen_pequiv_hhinc_filter %>%
  group_by(syear) %>%
  summarise(
    income_per_person_by_year = mean(income_per_person, na.rm = TRUE)
  )

ggplot(income_per_person_by_year, aes(x = syear, y = income_per_person_by_year)) + 
  geom_line(color = "mediumseagreen", linewidth = 0.2) + 
  geom_point(color = "mediumseagreen", size = 2) + 
  labs(title = "Average Income Per Person in HH by Year",
       x = "Year",
       y = "Average Income Per Person (EUR)") +
  theme_minimal()

Education and Employment

Education generally contributes to higher happiness through improved financial stability, better health, and enhanced social and psychological benefits. It often leads to greater job satisfaction and a sense of achievement.

Education plays a crucial role in shaping an individual’s life opportunities and overall well-being. This part explores the relationship between educational attainment and employment status, as well as their combined impact on life satisfaction.

Average Years of Education by Year

The graph illustrates the trend in average years of education from 1984 to 2020.

Main observations:

The graph shows a clear upward trend in the average years of education from 1980 to around 2010, followed by fluctuations in the subsequent years. This indicates a general increase in the number of years individuals spend in education over the 40-year period.

pequiv_edu_data <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11108", "d11109"))

pequiv_edu_data <- pequiv_edu_data %>%
  rename(
    `education_HS` = d11108,
    `years_of_Education` = d11109
  )

pequiv_edu_data_filter <- pequiv_edu_data %>%
  mutate(education_HS = as.numeric(education_HS), years_of_Education = as.numeric(years_of_Education)) %>%
  filter(years_of_Education > 0, education_HS > 0)

average_years_of_education_by_year <- pequiv_edu_data_filter %>%
  group_by(syear) %>%
  summarize(Mean_Years_of_Education = mean(years_of_Education, na.rm = TRUE))

# 349,070 entries
ggplot(average_years_of_education_by_year, aes(x = syear, y = Mean_Years_of_Education)) +
  geom_line(color = "mediumseagreen", linewidth = 0.2) +  
  geom_point(color = "mediumseagreen", size = 2) +   
  labs(title = "Average Years of Education by Year",
       x = "Year",
       y = "Average Years of Education") +
  theme_minimal()

Average Years of Education by Year and Education Level

The faceted plot highlights distinct trends for each educational level, emphasizing the different trajectories and growth patterns.

Main observations:

For “Less than HS,” there is a noticeable increase followed by stabilization, indicating efforts to enhance basic education access.

The “High School” category shows consistent growth, reflecting increased retention and completion rates.

The “More than HS” category shows a pronounced upward trend, emphasizing the growing demand for advanced education and professional qualifications.

The gap between the average years of education for those with “More than HS” and those with only “High School” education has widened over time. This suggests increasing stratification based on educational attainment, which could have implications for income inequality, employment opportunities, and social mobility.

average_education_HS_by_year <- pequiv_edu_data_filter %>%
  group_by(syear, education_HS) %>%
  summarize(Mean_Years_of_Education = mean(years_of_Education, na.rm = TRUE))

ggplot(average_education_HS_by_year, aes(x = syear, y = Mean_Years_of_Education, color = as.factor(education_HS))) +
  geom_line(linewidth = 0.2) +
  geom_point(size = 1.1) +
  labs(title = "Average Years of Education by Year and Education Level",
       x = "Year",
       y = "Average Years of Education",
       color = "Education Level") +
  scale_color_manual(values = c("1" = "tomato", "2" = "mediumseagreen", "3" = "cornflowerblue"),
                     labels = c("1" = "Less than HS", "2" = "High School", "3" = "More than HS")) +
  theme_minimal()

This is a faceted plot, which divides the data into three panels, each corresponding to one of the educational levels, allowing for a detailed examination of trends within each category over the specified years.

ggplot(average_education_HS_by_year, aes(x = syear, y = Mean_Years_of_Education)) +
  geom_line(color = "mediumseagreen", linewidth = 0.2) +
  geom_point(color = "mediumseagreen", size = 1.1) +
  labs(title = "Average Years of Education by Year and Education Level",
       x = "Year",
       y = "Average Years of Education") +
  facet_wrap(~ education_HS, scales = "free_y", labeller = as_labeller(c(
    `1` = "Less than HS",
    `2` = "High School",
    `3` = "More than HS"
  ))) +
  theme_minimal()

Education and employment status

This is a violin plot showing the distribution of years of education across different employment statuses, considered in pgen.dta.

Main observations:

  1. Full-Time Employment: Individuals with full-time employment generally have a higher level of education. The plot is more concentrated around higher years of education, with a notable peak at around 15 years, indicating that many individuals in this category have some college education or higher.

  2. Regular Part-Time and Vocational Training: These groups show similar patterns, with a slight peak around 12-15 years of education. This suggests that many individuals in these categories have completed high school and some have attended college or vocational training programs.

  3. Marginal/Irregular Part-Time and Not Employed: These groups have a broader distribution of years of education, with many individuals having less than a high school education and others having more. This spread indicates a wide range of educational backgrounds among these individuals.

  4. Sheltered Workshop: This group shows a unique distribution, with most individuals having fewer years of education, typically less than high school.

pequiv_edu <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11109"))

pequiv_edu <- pequiv_edu %>%
  rename(
    `years_of_Education` = d11109
  )

pgen_empl <- read_dta("C:/R/final project/data/pgen.dta", col_select = c("cid", "hid", "pid", "syear", "pgemplst"))

pequiv_pgen_edu <- full_join(pequiv_edu, pgen_empl, by = c("pid", "hid", "cid", "syear"))

pequiv_pgen_edu <- na.omit(pequiv_pgen_edu) %>% 
  filter(years_of_Education >= 0, pgemplst >= 0)

pequiv_pgen_edu <- pequiv_pgen_edu %>%
  mutate(pgemplst = factor(pgemplst, levels = 1:6, 
                           labels = c("Full-Time Employment", 
                                      "Regular Part-Time", 
                                      "Vocational Training", 
                                      "Marginal/Irregular Part-Time", 
                                      "Not Employed", 
                                      "Sheltered Workshop")))

ggplot(pequiv_pgen_edu, aes(x = pgemplst, y = years_of_Education)) +
  geom_violin(fill = "tomato", color = "black", alpha = 0.7) +
  labs(
    title = "Years of Education by Employment Status",
    x = "Employment Status",
    y = "Years of Education"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Life satisfaction and employment status

This box plot showing the distribution of life satisfaction scores (on a scale from 0 to 10) across the same employment statuses.

Main observations:

Not Employed and Sheltered Workshop groups generally report lower life satisfaction, with median scores slightly lower than the employed groups. The range of scores is wider, suggesting greater variability in life satisfaction among individuals who are not employed or in sheltered workshops. Some individuals report high life satisfaction, while others report very low satisfaction.

The gap in education levels between different employment categories (e.g., full-time vs. not employed) suggests a stratification in employment opportunities based on educational attainment. Those with higher education levels are more likely to secure stable employment, which is associated with higher life satisfaction.

pequiv_com <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "p11101"))

pequiv_com <- pequiv_com %>% filter_all(all_vars(. >= 0)) %>%
  rename(
    `lifesat` = p11101
  )

#381917
pgen_pequiv_job <- full_join(pgen_empl, pequiv_com, by = c("pid", "hid", "cid", "syear"))

#363978
pgen_pequiv_job <- na.omit(pgen_pequiv_job) %>% 
  filter(pgemplst >= 0, lifesat >= 0)


pgen_pequiv_job <- pgen_pequiv_job %>%
  mutate(pgemplst = factor(pgemplst, levels = 1:6, 
                           labels = c("Full-Time Employment", 
                                      "Regular Part-Time", 
                                      "Vocational Training", 
                                      "Marginal/Irregular Part-Time", 
                                      "Not Employed", 
                                      "Sheltered Workshop")))

# Boxplot of life satisfaction by employment status
ggplot(pgen_pequiv_job, aes(x = pgemplst, y = lifesat)) +
  geom_boxplot(fill = "cornflowerblue", color = "black", alpha = 0.7) +
  labs(
    title = "Life Satisfaction by Employment Status (1984-2020)",
    x = "Employment Status",
    y = "Life Satisfaction (0-10)"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Commuting

This section explores the relationship between commuting patterns and overall life satisfaction. By examining various metrics such as commuting distance, time, and frequency over different years, we can gain a deeper understanding of how changes in commuting behavior might influence happiness.

Mean Commuting Distance and Mean Commuting Time

The bar plot compares two different metrics over several years: Mean Commuting Distance (in kilometers) and Mean Commuting Time (in minutes). Each bar represents a different year, showing both metrics on the same graph using two different scales.

Main observations:

Over the years shown (2015, 2017, 2019 and 2021), we see variations in both commuting distance and time. For instance, the mean commuting distance increased from 2015 to 2017 and started slightly decreasing after, while the mean commuting time remained almost constant across these years.

Since 2017, commuting has decreased, likely due to the increase in remote work and online job opportunities. However, for those who continued to commute, the time spent traveling remained significant, possibly due to heavy traffic in cities.

pl_com <- read_dta("C:/R/final project/data/pl.dta", col_select = c("cid", "hid", "pid", "syear", "plb0592", "plb0591", "plb0590"))

pl_com <- pl_com %>%
  rename(
    `comtime` = plb0592,
    `comfreq` = plb0591,
    `comdist` = plb0590
  )
pl_com <- pl_com %>% 
  filter(comtime >= 0, comfreq >= 0, comdist >= 0) 

# Calculating statistical measures by year
commuting_stats_by_year <- pl_com %>%
  group_by(syear) %>%  
  summarise(
    Mean_Distance = mean(comdist, na.rm = TRUE),  
    Median_Distance = median(comdist, na.rm = TRUE),  
    Range_Distance = list(range(comdist, na.rm = TRUE)),  
    
    Mean_Time = mean(comtime, na.rm = TRUE), 
    Median_Time = median(comtime, na.rm = TRUE),   
    Range_Time = list(range(comtime, na.rm = TRUE)),  
    
    Mode_Frequency = names(sort(table(comfreq), decreasing = TRUE))[1]  # Calculate mode of commuting frequency
  )


ggplot(commuting_stats_by_year, aes(x = syear)) +
  geom_col(aes(y = Mean_Distance, fill = "Mean Distance (km)"), alpha = 0.6, width = 1, position = position_dodge(width = 0.5)) +
  geom_col(aes(y = Mean_Time, fill = "Mean Time (min)"), alpha = 0.9, width = 1, position = position_dodge(width = 0.5)) +
  labs(title = "Mean Distance and Commuting Time by Year",
       x = "Year",
       y = "Commuting Distance (km)") +
  scale_y_continuous(sec.axis = sec_axis(~., name = "Commuting Time (min)")) +
  scale_fill_manual(values = c("Mean Distance (km)" = "cornflowerblue", "Mean Time (min)" = "tomato"), name = "Values") +
  theme_minimal() +
  theme(axis.title.y = element_text(color = "cornflowerblue"),
        axis.title.y.right = element_text(color = "tomato"),
        legend.position = "bottom")

Commuting Distance vs. Time by Frequency of Commuting and Year

This scatter plot matrix visualizes the relationship between commuting distance (in km) and commuting time (in minutes) for different commuting frequencies and years. The different panels represent different years (2015, 2017, 2019), and the points are colored based on commuting frequency.

Main observations:

  • As expected, there is a general trend where longer commuting distances correspond to longer commuting times.
  • The black dashed line represents the mean commuting time for each distance category, and it appears that several people commute long distances relatively quickly (likely due to faster transportation means).
  • High-frequency commuters (red dots) tend to have more consistent commuting times, even at longer distances, especially in 2019, compared to lower-frequency commuters (blue and green dots).
ggplot(pl_com, aes(x = comdist, y = comtime)) +
  geom_point(aes(color = as.factor(comfreq)), alpha = 0.4) +
  geom_smooth(method = "lm", se = FALSE, color = "black", linetype = "dashed", linewidth = 0.6) +
  facet_grid(comfreq ~ syear) +  
  labs(title = "Commuting Distance vs. Time by Frequency of Commuting and Year",
       x = "Distance (km)",
       y = "Commuting Time (min)",
       color = "Commuting Frequency") +
  scale_color_manual(
    values = c("1" = "tomato", "2" = "mediumseagreen", "3" = "cornflowerblue"), 
    labels = c(
      "1" = "Several times a week",
      "2" = "Once a week",
      "3" = "Less"
    )
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

Interactive Scatter Plot of Commuting Time vs. Life Satisfaction by Year

The scatter plot illustrates the relationship between commuting time (in minutes) and life satisfaction across three different years: 2015, 2017, and 2019. During the data preparation process, the initial dataset of circa 400,000 respondents was significantly reduced, leaving only 354 respondents for analysis.

Main observations:

  • Across all three years, life satisfaction scores range from 0 to 10. The distribution is somewhat consistent, with a majority of scores falling between 4 and 10.

  • Over the years, there is a consistent observation that moderate commuting times (under 100 minutes) are associated with higher life satisfaction scores, which generally range from 6 to 8.

  • A noticeable trend is the increase in lower life satisfaction scores among those with longer commuting times, especially in 2019.

pl_pequiv_comtime_sat <- full_join(pl_com, pequiv_com, by = c("pid", "hid", "cid", "syear"))

pl_pequiv_comtime_sat <- na.omit(pl_pequiv_comtime_sat)


pl_pequiv_comtime_sat <- pl_pequiv_comtime_sat %>%
  mutate(across(where(is.labelled), ~ as.numeric(as.character(.))))

# Spliting the data by 'syear'
pl_pequiv_comtime_sat_split <- split(pl_pequiv_comtime_sat, pl_pequiv_comtime_sat$syear)

library(plotly)

# Defining colors for each year
colors <- c('2015' = 'cornflowerblue', '2017' = 'mediumseagreen', '2019' = 'tomato')

# Creating individual plots for each year
plots <- lapply(names(pl_pequiv_comtime_sat_split), function(year) {
  plot_ly(
    data = pl_pequiv_comtime_sat_split[[year]], 
    x = ~comtime, 
    y = ~lifesat, 
    type = 'scatter', 
    mode = 'markers',
    marker = list(size = 10, color = colors[year],
                  line = list(color = 'black', width = 0.5)),
    name = paste("Year:", year) 
  ) %>%
    layout(
      title = paste("Year:", year),
      xaxis = list(title = "Commuting Time (min)", 
                   titlefont = list(size = 10)),
      yaxis = list(title = "Life Satisfaction")
    )
})

# Combineing plots into a subplot
subplot(
  plots[[1]], # 2015
  plots[[2]], # 2017
  plots[[3]], # 2019
  nrows = 1, # Arrange in a single row
  shareX = TRUE, 
  shareY = TRUE, 
  titleX = TRUE, 
  titleY = TRUE, 
  margin = 0.05 
) %>%
  layout(
    title = "Interactive Scatter Plot of Commuting Time vs. Life Satisfaction by Year",
    showlegend = TRUE,
    legend = list(
      font = list(size = 10)
  ))

This correlation proves the plot´s results and shows the absence of almost any direct connection between commuting time and life satisfaction.

cor_time_lifesat <- cor(pl_pequiv_comtime_sat$comtime, pl_pequiv_comtime_sat$lifesat, use = "complete.obs")
print(paste("Correlation coefficient of life satisfaction and commuting time:", cor_time_lifesat))
## [1] "Correlation coefficient of life satisfaction and commuting time: 0.0140971713975234"

The analysis of commuting patterns over the years reveals several important trends.

* First, the decrease in commuting distances post-2017 likely reflects the growing adoption of remote work, yet commuting time has remained largely unchanged, highlighting persistent inefficiencies in transportation. 

* Second, frequent commuters tend to have more predictable and consistent commuting times, suggesting that experience or access to better transport options plays a role in managing commutes effectively. 

* Finally, while longer commutes can negatively impact life satisfaction, the relationship is complex and likely influenced by various external factors.

These insights emphasize the importance of understanding the broader context of commuting behaviors and their impact on well-being.

Income and life satisfaction

In a previous section, I examined household income and individual income per family member, observing a steady increase in both over nearly 40 years. Building on these findings, this part delves deeper into the relationship between individual income and life satisfaction. Understanding how personal financial stability influences well-being can provide valuable insights into the broader socioeconomic factors that contribute to happiness and overall quality of life. This analysis aims to explore whether rising incomes are consistently linked to higher levels of life satisfaction.

Correlation between household income and life satisfaction

This correlation suggests that increasing household income can contribute to improved life satisfaction, but it is not the sole factor.

pequiv_lifesat <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "p11101"))

pequiv_lifesat <- pequiv_lifesat %>% 
  rename(
    life_sat = p11101
  )
  
# Merging the two datasets by pid and syear
pl_pequiv_sat <- full_join(pl_hhinc_data, pequiv_lifesat, by = c("pid", "hid", "cid", "syear"))

pl_pequiv_sat <- na.omit(pl_pequiv_sat)

pl_pequiv_sat <- pl_pequiv_sat %>%
  filter_all(all_vars(. >= 0))


correlation_incsat_lifesat <- round(cor(pl_pequiv_sat$life_sat, pl_pequiv_sat$hhinc_sat, use = "complete.obs"), 3)

print(paste("Correlation coefficient between satisfaction with hausehold income and overall life satisfaction:", correlation_incsat_lifesat))
## [1] "Correlation coefficient between satisfaction with hausehold income and overall life satisfaction: 0.486"

Correlation between Overall Life Satisfaction and Satisfaction With Personal Income by Year

The provided graph illustrates the correlation between overall life satisfaction and satisfaction with personal income from 1984 to 2020.

Post-1990, there is a decline in the correlation, followed by several fluctuations. The decline in the correlation from the mid-2000s onward suggests that the association between life satisfaction and income satisfaction became weaker over time. This could imply that factors other than income satisfaction may have started to play a more significant role in determining overall life satisfaction.

pl_pequiv_sat_cor <- pl_pequiv_sat %>%
  group_by(syear) %>%
  summarise(
    Correlation = cor(life_sat, hhinc_sat, use = "complete.obs")
  )

ggplot(pl_pequiv_sat_cor, aes(x = syear, y = Correlation)) +
  geom_line(color = "cornflowerblue", linewidth = 0.2) +
  geom_point(color = "cornflowerblue", size = 2) +
  labs(title = "Correlation between Overall Life Satisfaction and Satisfaction With Personal Income by Year",
       x = "Year",
       y = "Correlation Coefficient") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, size = 10) ) +
  scale_x_continuous(breaks = seq(min(pl_pequiv_sat_cor$syear), max(pl_pequiv_sat_cor$syear), by = 2)) 

The “Comparison of Mean Per Capita Income and Life Satisfaction by Year” graph compares the trends in mean per capita income and mean life satisfaction over time, illustrating their separate trajectories and relative scales.

The parallel increase in both income and life satisfaction suggests a positive correlation between financial well-being and overall happiness. However, the less pronounced rise in life satisfaction compared to income growth indicates diminishing returns. After a certain point, additional income may have a reduced impact on life satisfaction.
pequiv_hhsize_data <- read_dta("C:/R/final project/data/pequiv.dta", col_select = c("cid", "hid", "pid", "syear", "d11106", "d11107","p11101"))

pequiv_hhsize_data <- pequiv_hhsize_data %>%
  rename(
    `hh_size` = d11106,
    `hh_child` = d11107,
    `life_sat` = p11101
  )

hgen_pequiv_merged <- full_join(hgen_hhinc_data, pequiv_hhsize_data, by = c("cid", "hid", "syear"))

hgen_pequiv_merged <- na.omit(hgen_pequiv_merged)
hgen_pequiv_merged <- hgen_pequiv_merged %>% filter(monthly_hhinc >= 0, hh_size > 0, hh_child >= 0, life_sat >= 0) %>% 
  filter(hh_size > hh_child)

# Calculating Per Capita Household Income
hgen_pequiv_merged <- hgen_pequiv_merged %>%
  mutate(
    per_capita_income = monthly_hhinc / (hh_size - hh_child)
  )

# Calculating the mean per capita income and life satisfaction by year
hgen_pequiv_mean <- hgen_pequiv_merged %>%
  group_by(syear) %>%
  summarize(
    mean_per_capita_income = round(mean(per_capita_income, na.rm = TRUE), 1),
    mean_life_sat = round(mean(life_sat, na.rm = TRUE), 1)
  )

# mean per capita income and mean life satisfaction by year
scale_factor <- max(hgen_pequiv_mean$mean_per_capita_income, na.rm = TRUE) / max(hgen_pequiv_mean$mean_life_sat, na.rm = TRUE)

# mean per capita income and mean life satisfaction by year
 scale_factor <- max(hgen_pequiv_mean$mean_per_capita_income) / max(hgen_pequiv_mean$mean_life_sat)
 
  ggplot(hgen_pequiv_mean, aes(x = syear)) +
   geom_line(aes(y = mean_per_capita_income, color = "Mean Per Capita Income"), linewidth = 0.2) +
   geom_point(aes(y = mean_per_capita_income, color = "Mean Per Capita Income"), size = 1.6) +
   geom_line(aes(y = mean_life_sat * scale_factor, color = "Mean Life Satisfaction"), linewidth = 0.2) +
   geom_point(aes(y = mean_life_sat * scale_factor, color = "Mean Life Satisfaction"), size = 1.6) +
   scale_y_continuous(
     name = "Mean Per Capita Income",
     sec.axis = sec_axis(~ . / scale_factor, name = "Mean Life Satisfaction")
   ) +
   labs(
     title = "Comparison of Mean Per Capita Income and Life Satisfaction by Year",
     x = "Year",
     color = "Metrics"
   ) +
   theme_minimal() +
   scale_color_manual(values = c("Mean Per Capita Income" = "cornflowerblue", "Mean Life Satisfaction" = "tomato"))
A correlation coefficient of 0.465 indicates a moderate positive relationship between the two variables in question. It suggests that there is a moderate tendency for higher satisfaction with personal income to be associated with higher overall life satisfaction, but it also indicates that other factors may be contributing to overall life satisfaction.
  cor_pinc_lifesat <- round(cor(hgen_pequiv_mean$mean_per_capita_income, hgen_pequiv_mean$mean_life_sat, use = "complete.obs"), 3)
  print(paste("Correlation coefficient of life satisfaction and commuting time:", cor_pinc_lifesat))
## [1] "Correlation coefficient of life satisfaction and commuting time: 0.465"

The analysis of income and life satisfaction data over several decades reveals a nuanced relationship between financial well-being and happiness. While income growth is positively correlated with increased life satisfaction, the relationship is not absolute. The correlation between income satisfaction and overall life satisfaction has declined over time, suggesting the growing importance of non-financial factors in shaping well-being. These findings highlight the complexity of happiness, where financial security is necessary but not sufficient.

Conclusion

The analysis of the relationship between happiness (measured as life satisfaction) and commuting, as well as other socio-economic factors, reveals a complex interplay of variables that influence individual well-being.

Main findings:

All factors examined in this study—demographics, income, education, employment, and commuting—are interconnected in their influence on happiness. Demographics shape commuting behaviors and preferences, which, in turn, affect life satisfaction. Income and education not only determine the quality of employment but also influence the choice of commuting methods and distances. Employment status directly affects commuting patterns, as full-time and stable jobs may require longer commutes, while flexible or remote jobs may reduce the need for commuting altogether.

Appendix

Variables´ names

pequiv.dta

d11101: Age

d11102ll: Gender

d11104: Marital Status

d11106: Number of persons in HH

d11109: Number of Years of Education

d11108: Education With Respect to High School

pgen.dta

pgemplst: Employment Status

pl.dta

plh0175: HH income satisfaction

plb0590: Distance 1. Dwelling - 2. Dwelling

plb0591: Commuting Frequency

plb0592: Commuting Time (Minutes)

hgen.dta

hghinc: Monthly HH income

References

Clark, B., Chatterjee, K., Martin, A., & Davis, A. (2019). How commuting affects subjective wellbeing. Transportation, 47, 2777–2805. https://doi.org/10.1007/s11116-019-09983-9
Kahneman, D., Krueger, A. B., Schkade, D., Schwarz, N., & Stone, A. A. (2004). A survey method for characterizing daily life experience: The day reconstruction method. Science, 306(5702), 1776–1780. https://doi.org/10.1126/science.1103572
Meier, S., & Stutzer, A. (2008). Is volunteering rewarding in itself? Economica, 75(297), 39–59. https://doi.org/10.1111/j.1468-0335.2007.00597.x
Petrunoff, N., Rissel, C., & Wen, L. M. (2017). The effect of active travel interventions conducted in work settings on driving to work: A systematic review. International Journal of Environmental Research and Public Health, 14(10), 1176. https://doi.org/10.3390/ijerph14101176
Stutzer, A., & Frey, B. S. (2008). Stress that doesn’t pay: The commuting paradox. Scandinavian Journal of Economics, 110(2), 339–366. https://doi.org/10.1111/j.1467-9442.2008.00542.x
DQotLS0NCnRpdGxlOiAiSGFwcGluZXNzIGFuZCBDb21tdXRpbmcgKFNPRVApIg0KYXV0aG9yOiAiQW5hc3Rhc2lpYSBBcGF0ZW5rbyAobWF0cmljdWxhdGlvbiBudW1iZXI6IDE0MzczMikiDQpkYXRlOiAiMjAyNC0wOC0zMCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgY3NzOiBjdXN0b21fc3R5bGUuY3NzDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICBrZWVwX3RleDogdHJ1ZQ0KYmlibGlvZ3JhcGh5OiBGaW5hbF8xNDM3MzIuYmliDQpjc2w6IEM6L1IvZmluYWwgcHJvamVjdC9hcGEuY3NsDQpsaW5rLWNpdGF0aW9uczogdHJ1ZQ0KYWx3YXlzX2FsbG93X2h0bWw6IHRydWUNCmtuaXRyOg0KICBvcHRzX2NodW5rOg0KICAgIGVjaG86IHRydWUNCi0tLQ0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCg0KIyBEZWZhdWx0IHRvIHNob3dpbmcgY29kZSBpbiBIVE1MDQpvcHRzX2NodW5rJHNldCgNCiAgZWNobyA9IFRSVUUsICAgICAgICAgICAjIFNob3cgY29kZSBieSBkZWZhdWx0DQogIG1lc3NhZ2UgPSBGQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFDQopDQoNCiMgQ29uZGl0aW9uYWxseSBoaWRlIGNvZGUgaW4gUERGDQppZiAoa25pdHI6OmlzX2xhdGV4X291dHB1dCgpKSB7DQogIG9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSkNCn0NCmxpYnJhcnkoaGF2ZW4pDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkod3JpdGV4bCkNCmxpYnJhcnkocGxvdGx5KQ0KDQoNCmBgYA0KDQoNCiAgICAgDQojIEludHJvZHVjdGlvbiB7LnRhYnNldH0NCg0KVW5kZXJzdGFuZGluZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaGFwcGluZXNzIGFuZCBjb21tdXRpbmcgaXMgYSBzaWduaWZpY2FudCBhcmVhIG9mIGludGVyZXN0IGluIHNvY2lhbCBzY2llbmNlIHJlc2VhcmNoLiBDb21tdXRpbmcsIGRlZmluZWQgYXMgdGhlIGRhaWx5IHRyYXZlbCB0aW1lIHRvIGFuZCBmcm9tIHdvcmssIGlzIGFuIGludGVncmFsIHBhcnQgb2YgbWFueSBpbmRpdmlkdWFscycgbGl2ZXMsIHBhcnRpY3VsYXJseSBpbiB1cmJhbiBzZXR0aW5ncy4gUHJldmlvdXMgc3R1ZGllcyBoYXZlIGhpZ2hsaWdodGVkIHRoYXQgY29tbXV0aW5nIHRpbWUgY2FuIGltcGFjdCB2YXJpb3VzIGRpbWVuc2lvbnMgb2Ygd2VsbC1iZWluZywgaW5jbHVkaW5nIHBoeXNpY2FsIGhlYWx0aCwgbWVudGFsIGhlYWx0aCwgYW5kIG92ZXJhbGwgbGlmZSBzYXRpc2ZhY3Rpb24uIEFzIGNpdGllcyBncm93IGFuZCBjb21tdXRpbmcgdGltZXMgbGVuZ3RoZW4sIGludmVzdGlnYXRpbmcgaG93IGNvbW11dGluZyBhZmZlY3RzIGhhcHBpbmVzcyBiZWNvbWVzIGluY3JlYXNpbmdseSByZWxldmFudC4NCg0KIyMgU09FUCBkYXRhIA0KPGltZyBzcmM9Imh0dHBzOi8vd3d3LmRpdy5kZS9zaXhjbXMvbWVkaWEucGhwL2Rpd18xLmEuNzEuZGUvYmlsZF9jb250ZW50YmVyZWljaF9nYWxsZXJpYS9zb2VwdHV0b3JpYWxzX3RvcGljcy5qcGciIA0KICAgICBzdHlsZT0iZmxvYXQ6IGxlZnQ7IG1hcmdpbi1yaWdodDogMTVweDsgbWFyZ2luLWJvdHRvbTogMTBweDsiIHdpZHRoPSIzMDAiLz4NCiAgICAgDQpUaGUgU29jaW8tRWNvbm9taWMgUGFuZWwgKihTT0VQKSogaXMgYSBsb25naXR1ZGluYWwgc3VydmV5IHRoYXQgaGFzIGJlZW4gY29uZHVjdGVkIGFubnVhbGx5IHNpbmNlIDE5ODQgYnkgdGhlIEdlcm1hbiBJbnN0aXR1dGUgZm9yIEVjb25vbWljIFJlc2VhcmNoIChESVcgQmVybGluKS4gSXQgcHJvdmlkZXMgYSByaWNoLCBtdWx0aS1kaW1lbnNpb25hbCBkYXRhc2V0IHRoYXQgaW5jbHVkZXMgZGV0YWlsZWQgaW5mb3JtYXRpb24gb24gaG91c2Vob2xkcyBhbmQgaW5kaXZpZHVhbHMgaW4gR2VybWFueSwgY292ZXJpbmcgYXNwZWN0cyBzdWNoIGFzIGluY29tZSwgZW1wbG95bWVudCwgZWR1Y2F0aW9uLCBoZWFsdGgsIGFuZCBsaWZlIHNhdGlzZmFjdGlvbi4gVGhlIFNPRVAgaXMgb25lIG9mIHRoZSBsYXJnZXN0IGFuZCBtb3N0IGNvbXByZWhlbnNpdmUgcGFuZWwgZGF0YXNldHMgYXZhaWxhYmxlLCBhbGxvd2luZyByZXNlYXJjaGVycyB0byBhbmFseXplIHRoZSBkeW5hbWljIGFzcGVjdHMgb2Ygc29jaW8tZWNvbm9taWMgY29uZGl0aW9ucyBhbmQgYmVoYXZpb3JzIG92ZXIgdGltZS4gSXQgaXMgYSB2YWx1YWJsZSByZXNvdXJjZSBmb3Igc3R1ZHlpbmcgdHJlbmRzIGFuZCBwYXR0ZXJucyB3aXRoaW4gdGhlIEdlcm1hbiBwb3B1bGF0aW9uLCBwcm92aWRpbmcgaW5zaWdodHMgaW50byBob3cgZWNvbm9taWMsIHNvY2lhbCwgYW5kIHBlcnNvbmFsIGZhY3RvcnMgaW50ZXJhY3QgdG8gc2hhcGUgaW5kaXZpZHVhbHMnIGxpdmVzIGFuZCBzb2NpZXRhbCBvdXRjb21lcy4NCg0KIyMgRGVmaW5pdGlvbiBvZiBLZXkgVGVybXMNCg0KSW4gdGhpcyBzdHVkeSwgX19fSGFwcGluZXNzX19fIGlzIGRlZmluZWQgYXMgdGhlIHNlbGYtcmVwb3J0ZWQgbGlmZSBzYXRpc2ZhY3Rpb24gc2NvcmUsIGFzIG1lYXN1cmVkIGluIHRoZSBTb2Npby1FY29ub21pYyBQYW5lbCAoU09FUCkgZGF0YXNldC4gX19fQ29tbXV0aW5nX19fIHJlZmVycyB0byB0aGUgdG90YWwgdGltZSBhbiBpbmRpdmlkdWFsIHNwZW5kcyB0cmF2ZWxpbmcgZnJvbSBob21lIHRvIHdvcmsgYW5kIGJhY2ssIHR5cGljYWxseSBtZWFzdXJlZCBpbiBtaW51dGVzIHBlciBkYXkuDQpfX19MaWZlIHNhdGlzZmFjdGlvbl9fXyBpcyBhIHN1YmplY3RpdmUgYXNzZXNzbWVudCBvZiBvbmUncyBvdmVyYWxsIHdlbGwtYmVpbmcgYW5kIGNvbnRlbnRtZW50IHdpdGggbGlmZS4gTGlmZSBzYXRpc2ZhY3Rpb24gd2FzIGNob3NlbiBhcyB0aGUgbWVhc3VyZSBvZiBoYXBwaW5lc3MgYmVjYXVzZSBubyBvdGhlciBtb3JlIHN1aXRhYmxlIHZhcmlhYmxlcyB3ZXJlIGF2YWlsYWJsZSBpbiB0aGUgZGF0YSBzZXRzIGFjY2Vzc2libGUgdG8gdXMgdG8gZGVzY3JpYmUgdGhlIGxldmVsIG9mIGhhcHBpbmVzcy4NCg0KIyMgTGl0ZXJhdHVyZSBSZXZpZXcNCg0KVGhlIGV4aXN0aW5nIGxpdGVyYXR1cmUgaW5kaWNhdGVzIHRoYXQgY29tbXV0aW5nIGhhcyBzaWduaWZpY2FudCBpbXBsaWNhdGlvbnMgZm9yIGFuIGluZGl2aWR1YWwncyBzdWJqZWN0aXZlIHdlbGwtYmVpbmcsIHdpdGggdmFyaW91cyBzdHVkaWVzIHJldmVhbGluZyBib3RoIGRpcmVjdCBhbmQgaW5kaXJlY3QgZWZmZWN0cyBvbiBoYXBwaW5lc3MuIFN0dXR6ZXIgYW5kIEZyZXkgW0BTdHV0emVyMjAwOF0gZGVzY3JpYmUgdGhlICJjb21tdXRpbmcgcGFyYWRveCwiIHdoZXJlIGxvbmdlciBjb21tdXRpbmcgdGltZXMsIGRlc3BpdGUgcG90ZW50aWFsIGZpbmFuY2lhbCBvciBlbXBsb3ltZW50IGJlbmVmaXRzLCBhcmUgY29uc2lzdGVudGx5IGxpbmtlZCB0byBsb3dlciBsZXZlbHMgb2YgbGlmZSBzYXRpc2ZhY3Rpb24uIFRoaXMgcGFyYWRveCB1bmRlcnNjb3JlcyB0aGUgcHN5Y2hvbG9naWNhbCBzdHJlc3MgYW5kIHJlZHVjZWQgdGltZSBmb3IgcGVyc29uYWwgYW5kIHNvY2lhbCBhY3Rpdml0aWVzIHRoYXQgbG9uZ2VyIGNvbW11dGVzIG9mdGVuIGVudGFpbC4gS2FobmVtYW4gZXQgYWwuIFtAS2FobmVtYW4yMDA0XSBmdXJ0aGVyIGVtcGhhc2l6ZSB0aGUgbmVnYXRpdmUgaW1wYWN0IG9mIGNvbW11dGluZyBvbiBkYWlseSB3ZWxsLWJlaW5nIGJ5IHVzaW5nIHRoZSBEYXkgUmVjb25zdHJ1Y3Rpb24gTWV0aG9kIChEUk0pIHRvIGNhdGVnb3JpemUgY29tbXV0aW5nIGFzIG9uZSBvZiB0aGUgbGVhc3QgZW5qb3lhYmxlIGRhaWx5IGFjdGl2aXRpZXMuIFRoZWlyIHJlc2VhcmNoIHNob3dzIHRoYXQgY29tbXV0aW5nIHNpZ25pZmljYW50bHkgY29udHJpYnV0ZXMgdG8gZGFpbHkgc3RyZXNzIGFuZCBvdmVyYWxsIGRpc3NhdGlzZmFjdGlvbiB3aXRoIGxpZmUsIHVuZGVyc2NvcmluZyBpdHMgcm9sZSBpbiBzaGFwaW5nIGRhaWx5IGV4cGVyaWVuY2VzLg0KDQpNZWllciBhbmQgU3R1dHplciBbQE1laWVyMjAwOF0gY29udHJpYnV0ZSB0byB0aGlzIGRpc2N1c3Npb24gYnkgZXhwbG9yaW5nIHRoZSBicm9hZGVyIGNvbnRleHQgb2YgdGltZSB1c2UgYW5kIGl0cyBpbmZsdWVuY2Ugb24gaGFwcGluZXNzLiBBbHRob3VnaCB0aGVpciBzdHVkeSBwcmltYXJpbHkgaW52ZXN0aWdhdGVzIHRoZSBiZW5lZml0cyBvZiB2b2x1bnRlZXJpbmcsIHRoZXkgbm90ZSB0aGF0IHRpbWUgc3BlbnQgY29tbXV0aW5nIGNhbiByZWR1Y2Ugb3Bwb3J0dW5pdGllcyBmb3IgZW5nYWdpbmcgaW4gZnVsZmlsbGluZyBhY3Rpdml0aWVzLCBzdWNoIGFzIHNvY2lhbGl6aW5nIG9yIHZvbHVudGVlcmluZywgd2hpY2ggYXJlIGNydWNpYWwgZm9yIG1haW50YWluaW5nIGhhcHBpbmVzcy4gVGhpcyBhbGlnbnMgd2l0aCBmaW5kaW5ncyBmcm9tIFBldHJ1bm9mZiBldCBhbC4gW0BQZXRydW5vZmYyMDE3XSwgd2hvIGhpZ2hsaWdodCB0aGUgYmVuZWZpdHMgb2YgYWN0aXZlIGNvbW11dGluZyBtb2Rlcywgc3VjaCBhcyB3YWxraW5nIG9yIGN5Y2xpbmcsIHBhcnRpY3VsYXJseSBpbiB3b3JrIHNldHRpbmdzLiBUaGVpciBzeXN0ZW1hdGljIHJldmlldyBzdWdnZXN0cyB0aGF0IGludGVydmVudGlvbnMgZW5jb3VyYWdpbmcgYWN0aXZlIGNvbW11dGluZyBjYW4gbWl0aWdhdGUgc29tZSBvZiB0aGUgbmVnYXRpdmUgaW1wYWN0cyBhc3NvY2lhdGVkIHdpdGggbG9uZ2VyIG9yIG1vcmUgc3RyZXNzZnVsIGNvbW11dGVzLCB0aHVzIGVuaGFuY2luZyBvdmVyYWxsIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCByZWR1Y2luZyBzdHJlc3MgbGV2ZWxzLg0KDQpDbGFyayBldCBhbC4gW0BDbGFyazIwMTldIGRlbHZlIGRlZXBlciBpbnRvIHRoZSBudWFuY2VzIG9mIGhvdyBkaWZmZXJlbnQgY29tbXV0aW5nIG1vZGVzIGFmZmVjdCBzdWJqZWN0aXZlIHdlbGwtYmVpbmcuIFRoZXkgZm91bmQgdGhhdCBpbmRpdmlkdWFscyBjb21tdXRpbmcgYnkgY2FyIHRlbmQgdG8gcmVwb3J0IGxvd2VyIGhhcHBpbmVzcyBsZXZlbHMgY29tcGFyZWQgdG8gdGhvc2Ugd2hvIHdhbGsgb3IgY3ljbGUsIHBvdGVudGlhbGx5IGR1ZSB0byB0aGUgYXNzb2NpYXRlZCBwaHlzaWNhbCBhY3Rpdml0eSBhbmQgZXhwb3N1cmUgdG8gbW9yZSBwbGVhc2FudCBlbnZpcm9ubWVudHMuIE1vcmVvdmVyLCB0aGUgc3R1ZHkgdW5kZXJzY29yZXMgdGhlIGltcG9ydGFuY2Ugb2YgcGVyY2VpdmVkIGNvbnRyb2wgb3ZlciBvbmUncyBjb21tdXRpbmcgbWV0aG9kIGluIGluZmx1ZW5jaW5nIGl0cyBpbXBhY3Qgb24gbGlmZSBzYXRpc2ZhY3Rpb24uIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGUgYWJpbGl0eSB0byBjaG9vc2Ugb25lJ3MgbW9kZSBvZiB0cmFuc3BvcnQsIGFuZCB0aGVyZWJ5IHBvdGVudGlhbGx5IHJlZHVjZSBjb21tdXRlLXJlbGF0ZWQgc3RyZXNzLCBwbGF5cyBhIHNpZ25pZmljYW50IHJvbGUgaW4gZGV0ZXJtaW5pbmcgdGhlIG92ZXJhbGwgd2VsbC1iZWluZyBvZiBjb21tdXRlcnMuDQoNCkRlc3BpdGUgdGhlIGV4dGVuc2l2ZSBib2R5IG9mIHJlc2VhcmNoIG9uIGNvbW11dGluZyBhbmQgaGFwcGluZXNzLCB0aGVyZSByZW1haW5zIGEgZ2FwIGluIHVuZGVyc3RhbmRpbmcgaG93IHZhcmlvdXMgc29jaW8tZWNvbm9taWMgYW5kIGRlbW9ncmFwaGljIGZhY3RvcnMsIHN1Y2ggYXMgaW5jb21lLCBlbXBsb3ltZW50IHN0YXR1cywgYW5kIGdlb2dyYXBoaWMgcmVnaW9uLCBpbnRlcmFjdCB3aXRoIGNvbW11dGluZyB0byBhZmZlY3QgaGFwcGluZXNzIGxldmVscy4NCg0KIyMgRGF0YSBzZXRzIGFuZCBWYXJpYWJsZXMNCg0KV2UgaGFkIGFjY2VzcyB0byBzaXggZGF0YXNldHM6IGdyaXBzdHIuZHRhLCBoZ2VuLmR0YSwgaGwuZHRhLCBwZXF1aXYuZHRhLCBwZ2VuLmR0YSwgYW5kIHBsLmR0YS4gQWZ0ZXIgdGhvcm91Z2hseSBleGFtaW5pbmcgZWFjaCBkYXRhc2V0LCBJIHNlbGVjdGVkIGZvdXIgdGhhdCBjb250YWluZWQgdGhlIG5lY2Vzc2FyeSBpbmZvcm1hdGlvbiBmb3IgbXkgYW5hbHlzaXM6IF9faGdlbi5kdGFfXywgX19wZXF1aXYuZHRhX18sIF9fcGdlbi5kdGFfXywgYW5kIF9fcGwuZHRhX18uIFRoZSBkYXRhc2V0cyBncmlwc3RyLmR0YSBhbmQgaGwuZHRhIHdlcmUgbm90IGluY2x1ZGVkIGluIHRoZSBmaW5hbCBhbmFseXNpcywgYXMgdGhleSBkaWQgbm90IGNvbnRhaW4gdGhlIHJlbGV2YW50IHZhcmlhYmxlcyBmb3IgbXkgcmVzZWFyY2guDQoNClRoZSBjaG9zZW4gZGF0YXNldHMgcHJvdmlkZWQgY29tcHJlaGVuc2l2ZSBkYXRhIG9uIGVtcGxveW1lbnQgc3RhdHVzLCBob3VzZWhvbGQgY2hhcmFjdGVyaXN0aWNzLCBsaWZlIHNhdGlzZmFjdGlvbiwgYW5kIGVkdWNhdGlvbmFsIGJhY2tncm91bmQsIHdoaWNoIHdlcmUgY3J1Y2lhbCBmb3IgdW5kZXJzdGFuZGluZyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBjb21tdXRpbmcgYmVoYXZpb3IuIEhvd2V2ZXIsIGl0J3MgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCBzb21lIHZhcmlhYmxlcyB3ZXJlIG5vdCBhdmFpbGFibGUgZHVlIHRvIHJlc3RyaWN0ZWQgYWNjZXNzLiBGb3IgaW5zdGFuY2UsIHRoZSByZXNpZGVuY2UgaW5mb3JtYXRpb24gdmFyaWFibGUgKGwxMTEwMSkgaW4gdGhlIHBlcXVpdi5kdGEgd2FzIGluYWNjZXNzaWJsZSwgd2hpY2ggbGltaXRlZCB0aGUgYW5hbHlzaXMgb2YgY2VydGFpbiBhc3BlY3RzIHJlbGF0ZWQgdG8gZ2VvZ3JhcGhpYyBhbmQgcmVzaWRlbnRpYWwgZmFjdG9ycy4NCg0KDQpfX1ZhcmlhYmxlcyBpbmNsdWRlZDpfXw0KDQoxLiBBZ2UNCg0KMi4gR2VuZGVyDQoNCjMuIE1hcml0YWwgU3RhdHVzDQoNCjQuIE51bWJlciBvZiBwZXJzb25zIGluIGhvdXNlaG9sZA0KDQo1LiBOdW1iZXIgb2YgeWVhcnMgb2YgZWR1Y2F0aW9uDQoNCjYuIEVkdWNhdGlvbiB3aXRoIHJlc3BlY3QgdG8gSGlnaCBTY2hvb2wNCg0KNy4gSG91c2Vob2xkIGluY29tZSBzYXRpc2ZhY3Rpb24NCg0KOC4gQ29tbXV0aW5nIGRpc3RhbmNlIA0KDQo5LiBDb21tdXRpbmcgRnJlcXVlbmN5DQoNCjEwLiBDb21tdXRpbmcgVGltZSAoTWludXRlcykNCg0KMTEuIE1vbnRobHkgaG91c2Vob2xkIGluY29tZQ0KDQoxMi4gRW1wbG95bWVudCBTdGF0dXMNCg0KDQpFYWNoIHZhcmlhYmxlIGluIHRoZSBkYXRhc2V0cyBpcyBhdmFpbGFibGUgZm9yIGRpZmZlcmVudCB0aW1lIHBlcmlvZHMuIFNvbWUgY292ZXIgdGhlIHdob2xlIGR1cmF0aW9uIG9mIHRoZSBTT0VQIHN0dWR5LCBmcm9tIDE5ODQgdG8gMjAyMCwgd2hpbGUgb3RoZXJzIGFyZSBvbmx5IGF2YWlsYWJsZSBmb3Igc3BlY2lmaWMgeWVhcnMuIEFzIGEgcmVzdWx0LCBJIHVzZWQgdGhlIHByaW1hcnkgdmFyaWFibGVzIGZvciB0aGUgZW50aXJlIHN0dWR5IHBlcmlvZCwgYnV0IHNvbWUgZGV0YWlsZWQgaW5kaWNhdG9ycyBhcmUgb25seSBhdmFpbGFibGUgZm9yIHNob3J0ZXIgdGltZXMuDQoNClRvIGhhbmRsZSB0aGUgbGFyZ2UgYW1vdW50IG9mIGRhdGEsIEkgYWxzbyBzaG9ydGVuZWQgdGhlIHJlc2VhcmNoIHBlcmlvZCBmb3Igc29tZSBhbmFseXNlcy4gVGhpcyBtYWRlIHRoZSBkYXRhIG1vcmUgbWFuYWdlYWJsZSBhbmQgaGVscGVkIGZvY3VzIG9uIHNwZWNpZmljIGFzcGVjdHMgb2YgdGhlIHN0dWR5Lg0KDQpPdmVyYWxsLCB0aGlzIGFwcHJvYWNoIGFsbG93ZWQgbWUgdG8gYW5hbHl6ZSBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgY29tbXV0aW5nIGJlaGF2aW9yIGluIGEgY2xlYXIgYW5kIG9yZ2FuaXplZCB3YXksIGRlc3BpdGUgdGhlIGNoYWxsZW5nZXMgd2l0aCBkYXRhIGF2YWlsYWJpbGl0eSBhbmQgc2l6ZS4NCg0KIyMgSHlwb3RoZXNlcyANCg0KQmFzZWQgb24gdGhlIGxpdGVyYXR1cmUgcmV2aWV3LCBJIGh5cG90aGVzaXplIHRoYXQgbG9uZ2VyIGNvbW11dGluZyB0aW1lcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGxvd2VyIGxldmVscyBvZiBoYXBwaW5lc3MuIEFkZGl0aW9uYWxseSwgSSBjbGFpbSB0aGF0IHRoaXMgcmVsYXRpb25zaGlwIG1heSB2YXJ5IGRlcGVuZGluZyBvbiBzb2Npby1lY29ub21pYyBmYWN0b3JzIHN1Y2ggYXMgaW5jb21lLCBlbXBsb3ltZW50IHN0YXR1cywgYW5kIGVkdWNhdGlvbi4NCg0KDQoNCg0KIyBEZW1vZ3JhcGhpY3MgQW5hbHlzaXMgey50YWJzZXR9DQpUbyBiZWdpbiwgd2Ugd2lsbCBleGFtaW5lIHRoZSBrZXkgZGVtb2dyYXBoaWMgdmFyaWFibGVzIG9mIFNPRVAgZGF0YTogX19fYWdlX19fLCBfX19nZW5kZXJfX18sIGFuZCBfX19tYXJpdGFsIHN0YXR1c19fXy4gQWxsIG9mIHRoZXNlIHZhcmlhYmxlcyBhcmUgY29udGFpbmVkIGluIHRoZSBfX19wZXF1aXYuZHRhX19fIGRhdGFiYXNlLiBUaGVzZSBkZW1vZ3JhcGhpYyBmYWN0b3JzIGFyZSBjcnVjaWFsIGFzIHRoZXkgcHJvdmlkZSBmb3VuZGF0aW9uYWwgY29udGV4dCBmb3IgdW5kZXJzdGFuZGluZyB0aGUgY2hhcmFjdGVyaXN0aWNzIG9mIHRoZSBwb3B1bGF0aW9uIHVuZGVyIHN0dWR5LiBBbmFseXppbmcgdGhlc2UgdmFyaWFibGVzIHdpbGwgaGVscCB1cyBpZGVudGlmeSBwYXR0ZXJucyBhbmQgY29ycmVsYXRpb25zIHRoYXQgbWF5IGluZmx1ZW5jZSBvdGhlciBhc3BlY3RzIG9mIHRoZSBzdHVkeSwgc3VjaCBhcyBoYXBwaW5lc3MgYW5kIGNvbW11dGluZyB0aW1lLiBVbmRlcnN0YW5kaW5nIHRoZSBkaXN0cmlidXRpb24gYW5kIGNoYXJhY3RlcmlzdGljcyBvZiB0aGVzZSBkZW1vZ3JhcGhpY3MgYWxsb3dzIHVzIHRvIGJldHRlciBpbnRlcnByZXQgdGhlIGJyb2FkZXIgc29jaWFsIGFuZCBlY29ub21pYyBkeW5hbWljcyBhdCBwbGF5Lg0KDQoNCg0KIyMgQXZlcmFnZSBBZ2UgYnkgWWVhcg0KDQojIyMgQWdlIERpc3RyaWJ1dGlvbiBieSBZZWFyDQoNClRoaXMgYm94IHBsb3QgZWZmZWN0aXZlbHkgaWxsdXN0cmF0ZXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgYWdlcyBvZiByZXNwb25kZW50cyBmcm9tIDE5ODQgdG8gMjAyMC4gSXQgcHJvdmlkZXMgYSBjbGVhciB2aWV3IG9mIHRoZSBfX19taW5pbXVtX19fIGFuZCBfX19tYXhpbXVtX19fIGFnZXMgZm9yIGVhY2ggeWVhciwgYWxsb3dpbmcgZm9yIGFuIGVhc3kgaWRlbnRpZmljYXRpb24gb2YgdGhlIGFnZSByYW5nZSBvdmVyIHRpbWUuIEFkZGl0aW9uYWxseSwgdGhlIHBsb3QgaGlnaGxpZ2h0cyB0aGUgX19fbWVkaWFuX19fIGFnZSBhbmQgc2hvd2Nhc2VzIHRoZSB2YXJpYWJpbGl0eSBpbiBhZ2VzIGFjcm9zcyBkaWZmZXJlbnQgeWVhcnMuDQoNCg0KPGNlbnRlcj4NCmBgYHtyIGFnZSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQoNCnBlcXVpdl9kZW0gPC0gcmVhZF9kdGEoIkM6L1IvZmluYWwgcHJvamVjdC9kYXRhL3BlcXVpdi5kdGEiLCBjb2xfc2VsZWN0ID0gYygiY2lkIiwgImhpZCIsICJwaWQiLCAic3llYXIiLCAiZDExMTAxIiwgImQxMTEwMmxsIiwgImQxMTEwNCIpKQ0KDQoNCnBlcXVpdl9kZW1fZmlsdGVyIDwtIHBlcXVpdl9kZW0gJT4lDQogIHJlbmFtZSgNCiAgICBgYWdlYCA9IGQxMTEwMSwNCiAgICBgZ2VuZGVyYCA9IGQxMTEwMmxsLA0KICAgIGBtYXJpdGFsIHN0YXR1c2AgPSBkMTExMDQNCiAgKQ0KDQpwZXF1aXZfZGVtX2ZpbHRlciA8LSBwZXF1aXZfZGVtX2ZpbHRlciAlPiUNCiAgbXV0YXRlKGFnZSA9IGFzLm51bWVyaWMoYWdlKSkgJT4lDQogIGZpbHRlcihhZ2UgPiAwKQ0KDQojIEFnZSBEaXN0cmlidXRpb24NCmdncGxvdChwZXF1aXZfZGVtX2ZpbHRlciwgYWVzKHggPSBhcy5mYWN0b3Ioc3llYXIpLCB5ID0gYWdlKSkgKyANCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibWVkaXVtc2VhZ3JlZW4iLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJBZ2UgRGlzdHJpYnV0aW9uIGJ5IFllYXIiLCB4ID0gIlllYXIiLCB5ID0gIkFnZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUpKSAgDQoNCmBgYA0KPC9jZW50ZXI+DQoNCiMjIyBBdmVyYWdlIEFnZSBieSBZZWFyDQoNClRoZSBncmFwaCBzaG93cyBmbHVjdHVhdGlvbnMgaW4gdGhlIF9fX2F2ZXJhZ2VfX18gYWdlIG92ZXIgdGhlIHllYXJzLiBUaGUgbGluZSBpbGx1c3RyYXRlcyB0aGUgZ2VuZXJhbCBkaXJlY3Rpb24gb3IgdHJlbmQgb2YgdGhlIGF2ZXJhZ2UgYWdlLCB3aGV0aGVyIGl0IGlzIGluY3JlYXNpbmcsIGRlY3JlYXNpbmcsIG9yIHJlbWFpbmluZyBzdGFibGUuDQoNCjxjZW50ZXI+DQpgYGB7ciBhZ2VfYnlfeWVhciwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQphdmVyYWdlX2FnZV9ieV95ZWFyIDwtIHBlcXVpdl9kZW1fZmlsdGVyICU+JQ0KICBncm91cF9ieShzeWVhcikgJT4lDQogIHN1bW1hcml6ZShhdmVyYWdlX2FnZSA9IG1lYW4oYWdlLCBuYS5ybSA9IFRSVUUpKQ0KDQpnZ3Bsb3QoYXZlcmFnZV9hZ2VfYnlfeWVhciwgYWVzKHggPSBzeWVhciwgeSA9IGF2ZXJhZ2VfYWdlKSkgKyANCiAgZ2VvbV9saW5lKGNvbG9yID0gInRvbWF0byIsIGxpbmV3aWR0aCA9IDAuMikgKyAgDQogIGdlb21fcG9pbnQoY29sb3IgPSAidG9tYXRvIiwgc2l6ZSA9IDIpICsgICANCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIEFnZSBieSBZZWFyIiwgeCA9ICJZZWFyIiwgeSA9ICJBdmVyYWdlIEFnZSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCjwvY2VudGVyPg0KDQpTdGFydGluZyBmcm9tIDE5OTAsIHRoZSBwbG90IHJldmVhbHMgYSBncmFkdWFsIGluY3JlYXNlIGluIHRoZSBtZWFuIGFnZSBvZiByZXNwb25kZW50cyB1cCB1bnRpbCBuZWFybHkgdGhlIGVuZCBvZiB0aGUgMjAxMHMuIE5vdGFibHksIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgZHJvcCBpbiBtZWRpYW4gYWdlIGluIDIwMTAgY29tcGFyZWQgdG8gMjAwOSwgd2l0aCB0aGUgbWVkaWFuIGFnZSBmYWxsaW5nIGZyb20gYXBwcm94aW1hdGVseSA0MiB0byAzNS4gRm9sbG93aW5nIHRoaXMgc2hhcnAgZGVjbGluZSwgdGhlIG1lZGlhbiBhZ2UgaGFzIG5vdCByaXNlbiBhYm92ZSAzNiBpbiBzdWJzZXF1ZW50IHllYXJzLCBpbmRpY2F0aW5nIGEgc3VzdGFpbmVkIHRyZW5kIG9mIHlvdW5nZXIgcmVzcG9uZGVudHMgaW4gdGhlIG1vcmUgcmVjZW50IGRhdGEuIFRoaXMgc2hpZnQgbWF5IHJlZmxlY3QgYnJvYWRlciBkZW1vZ3JhcGhpYyBjaGFuZ2VzIG9yIHNoaWZ0cyBpbiB0aGUgc3VydmV5IHBvcHVsYXRpb24gb3ZlciB0aW1lLg0KDQoNCiMjIEdlbmRlciBEaXN0cmlidXRpb24NCg0KVGhlIGhpc3RvZ3JhbSBpbGx1c3RyYXRlcyB0aGUgZ2VuZGVyIGRpc3RyaWJ1dGlvbiBvdmVyIHRpbWUgZnJvbSAxOTg0IHRvIDIwMjAuDQoNCiogVGhlIGdlbmRlciBwcm9wb3J0aW9ucyBleGhpYml0IGZsdWN0dWF0aW9ucyBvdmVyIHRoZSB5ZWFycywgd2l0aCBub3RpY2VhYmxlIHZhcmlhdGlvbnMgaW4gdGhlIHJhdGlvIG9mIG1hbGVzIHRvIGZlbWFsZXMgYWNyb3NzIGRpZmZlcmVudCBwZXJpb2RzLg0KKiBTaWduaWZpY2FudCBzaGlmdHMgY2FuIGJlIHNlZW4gYXQgY2VydGFpbiBwb2ludHMgaW4gdGltZSwgc3VjaCBhcyB0aGUgZWFybHkgMTk5MHMgYW5kIGFyb3VuZCAyMDAwLCByZWZsZWN0aW5nIGNoYW5nZXMgaW4gZ2VuZGVyIHJlcHJlc2VudGF0aW9uIHdpdGhpbiB0aGUgZGF0YXNldC4NCiogUmVjZW50IHllYXJzIHNob3cgYSBtb3JlIGJhbGFuY2VkIGdlbmRlciBkaXN0cmlidXRpb24sIHdpdGggcHJvcG9ydGlvbnMgY29udmVyZ2luZyB0b3dhcmRzIGVxdWFsIHJlcHJlc2VudGF0aW9uLg0KDQo8Y2VudGVyPg0KYGBge3IgZ2VuZGVyLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCnBlcXVpdl9kZW1fZmlsdGVyIDwtIHBlcXVpdl9kZW1fZmlsdGVyICU+JQ0KICBtdXRhdGUoZ2VuZGVyID0gYXMubnVtZXJpYyhnZW5kZXIpLA0KICAgICAgICAgc3llYXIgPSBhcy5udW1lcmljKHN5ZWFyKSkgJT4lDQogIGZpbHRlcihnZW5kZXIgPiAwKQ0KDQpwZXF1aXZfZGVtX2ZpbHRlciA8LSBwZXF1aXZfZGVtX2ZpbHRlciAlPiUNCiAgbXV0YXRlKGdlbmRlciA9IGZhY3RvcihnZW5kZXIsIGxldmVscyA9IGMoMSwgMiksIGxhYmVscyA9IGMoIk1hbGUiLCAiRmVtYWxlIikpKQ0KDQpnZW5kZXJfcHJvcG9ydGlvbl9ieV95ZWFyIDwtIHBlcXVpdl9kZW1fZmlsdGVyICU+JQ0KICBncm91cF9ieShzeWVhciwgZ2VuZGVyKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUNCiAgZ3JvdXBfYnkoc3llYXIpICU+JQ0KICBtdXRhdGUodG90YWwgPSBzdW0oY291bnQpLA0KICAgICAgICAgcHJvcG9ydGlvbiA9IGNvdW50IC8gdG90YWwgKiAxMDApDQoNCmdncGxvdChnZW5kZXJfcHJvcG9ydGlvbl9ieV95ZWFyLCBhZXMoeCA9IHN5ZWFyLCB5ID0gcHJvcG9ydGlvbiwgY29sb3IgPSBnZW5kZXIsIGdyb3VwID0gZ2VuZGVyKSkgKyANCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDAuMikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAyKSArDQogIGxhYnModGl0bGUgPSAiR2VuZGVyIERpc3RyaWJ1dGlvbiBPdmVyIFRpbWUiLCB4ID0gIlllYXIiLCB5ID0gIlByb3BvcnRpb24gKCUpIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiTWFsZSIgPSAic2t5Ymx1ZSIsICJGZW1hbGUiID0gInNhbG1vbiIpLA0KICAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJHZW5kZXIiKSArIA0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KPC9jZW50ZXI+DQoNCiMjIE1hcml0YWwgU3RhdHVzIERpc3RyaWJ1dGlvbg0KDQpUaGUgYmFyIHBsb3Qgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiBtYXJpdGFsIHN0YXR1c2VzIGFjcm9zcyBkaWZmZXJlbnQgeWVhcnMuIEVhY2ggY29sb3IgcmVwcmVzZW50cyBhIGRpZmZlcmVudCB5ZWFyLCBhbmQgdGhlIGhlaWdodCBvZiB0aGUgYmFycyByZXByZXNlbnRzIHRoZSBwcm9wb3J0aW9uIG9mIHJlc3BvbmRlbnRzIGluIGVhY2ggbWFyaXRhbCBzdGF0dXMgY2F0ZWdvcnkuDQoNCiogVGhlIG1ham9yaXR5IG9mIHJlc3BvbmRlbnRzIGFyZSBtYXJyaWVkLCB3aXRoIGEgY29uc2lzdGVudCBwcm9wb3J0aW9uIG9mIG92ZXIgNjAlIGFjcm9zcyB0aGUgeWVhcnMuDQoqIFRoZSBwcm9wb3J0aW9uIG9mIHNpbmdsZSBpbmRpdmlkdWFscyBpcyB0aGUgc2Vjb25kIGhpZ2hlc3QsIGZvbGxvd2VkIGJ5IHdpZG93ZWQsIGRpdm9yY2VkLCBhbmQgc2VwYXJhdGVkIGluZGl2aWR1YWxzLg0KKiBXZSBjYW4gYWxzbyBvYnNlcnZlIHRoYXQgc2luY2UgdGhlIG1pZC0yMDAwcywgdGhlIHBvcHVsYXJpdHkgb2YgZGl2b3JjZXMgaGFzIGluY3JlYXNlZCwgd2hpbGUgdGhlIG51bWJlciBvZiBtYXJyaWFnZXMgaGFzIHNpZ25pZmljYW50bHkgZGVjbGluZWQuIA0KKiBTaW1pbGFybHksIHRoZSBudW1iZXIgb2Ygc2luZ2xlIGluZGl2aWR1YWxzIGJlZ2FuIHRvIHJpc2Ugc2hhcnBseSBhcm91bmQgMjAxMC4NCg0KVGhlc2UgdHJlbmRzIG1heSBwb2ludCB0byBldm9sdmluZyBjdWx0dXJhbCwgc29jaWFsLCBhbmQgZWNvbm9taWMgZmFjdG9ycyBpbmZsdWVuY2luZyBwZW9wbGUncyBjaG9pY2VzIHJlZ2FyZGluZyBtYXJyaWFnZSBhbmQgcmVsYXRpb25zaGlwcy4NCg0KPGNlbnRlcj4NCmBgYHtyIG1hcml0YWxfc3RhdHVzLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCnBlcXVpdl9kZW1fZmlsdGVyIDwtIHBlcXVpdl9kZW1fZmlsdGVyICU+JQ0KICBmaWx0ZXIoYG1hcml0YWwgc3RhdHVzYCA+IDApICU+JSAgDQogIG11dGF0ZShgbWFyaXRhbCBzdGF0dXNgID0gZmFjdG9yKGBtYXJpdGFsIHN0YXR1c2AsICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gMTo1LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiTWFycmllZCIsICJTaW5nbGUiLCAiV2lkb3dlZCIsICJEaXZvcmNlZCIsICJTZXBhcmF0ZWQiKSkpDQoNCnN0YXRzX2J5X3llYXJfbWFyaXRhbF9zdGF0dXMgPC0gcGVxdWl2X2RlbV9maWx0ZXIgJT4lDQogIGdyb3VwX2J5KHN5ZWFyLCBgbWFyaXRhbCBzdGF0dXNgKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKQ0KDQoNCg0Kc3RhdHNfYnlfeWVhcl9tYXJpdGFsX3N0YXR1cyA8LSBzdGF0c19ieV95ZWFyX21hcml0YWxfc3RhdHVzICU+JQ0KICBncm91cF9ieShzeWVhcikgJT4lDQogIG11dGF0ZSh0b3RhbCA9IHN1bShjb3VudCksDQogICAgICAgICBwcm9wb3J0aW9uID0gY291bnQgLyB0b3RhbCAqIDEwMCkNCg0KZ2dwbG90KHN0YXRzX2J5X3llYXJfbWFyaXRhbF9zdGF0dXMsIGFlcyh4ID0gYG1hcml0YWwgc3RhdHVzYCwgeSA9IHByb3BvcnRpb24sIGZpbGwgPSBmYWN0b3Ioc3llYXIpKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGxhYnModGl0bGUgPSAiTWFyaXRhbCBTdGF0dXMgRGlzdHJpYnV0aW9uIGJ5IFllYXIgKFByb3BvcnRpb24pIiwgeCA9ICJNYXJpdGFsIFN0YXR1cyIsIHkgPSAiUHJvcG9ydGlvbiAoJSkiLCBmaWxsID0gIlllYXIiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA2KSwgIA0KICAgICAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDYpKQ0KYGBgDQo8L2NlbnRlcj4NCg0KDQojIEhvdXNlaG9sZCBhbmQgaW5kaXZpZHVhbCBpbmNvbWUgey50YWJzZXR9DQoNCkkgYW5hbHl6ZWQgaG91c2Vob2xkIGluY29tZSBkYXRhIHRvIGV4cGxvcmUgaG93IGF2ZXJhZ2UgbW9udGhseSBob3VzZWhvbGQgaW5jb21lIHZhcmllcyB3aXRoIHRoZSBudW1iZXIgb2YgaG91c2Vob2xkIG1lbWJlcnMgYW5kIGhvdyBpbmNvbWUgcGVyIHBlcnNvbiBpbiBhIGhvdXNlaG9sZCBjaGFuZ2VzIG92ZXIgdGhlIHllYXJzLiBUaGVzZSBhbmFseXNlcyBwcm92aWRlIGluc2lnaHRzIGludG8gaW5jb21lIGRpc3RyaWJ1dGlvbiBwYXR0ZXJucyBhbmQgdGhlaXIgcG90ZW50aWFsIGltcGFjdCBvbiBjb21tdXRpbmcgYmVoYXZpb3JzIGFuZCBvdmVyYWxsIGhhcHBpbmVzcy4NCg0KIyMgQXZlcmFnZSBtb250aGx5IGhvdXNlaG9sZCBpbmNvbWUgIA0KDQpIZXJlIEkgd2FudGVkIHRvIG1lcmdlIGFuZCBjbGVhbiBob3VzZWhvbGQgaW5jb21lIGFuZCBzaXplIGRhdGEsIHRoZW4gdmlzdWFsaXplIGhvdyBhdmVyYWdlIG1vbnRobHkgaG91c2Vob2xkIGluY29tZSB2YXJpZXMgd2l0aCB0aGUgbnVtYmVyIG9mIGhvdXNlaG9sZCBtZW1iZXJzIGFjcm9zcyB0aGUgeWVhcnMuIEJ1dCB0aGUgZGF0YSB3YXMgc28gdmFzdCBhbmQgdGhlcmUgdGhlcmUgbW9yZSB0aGFuIDEgbWlsbGlvbiB2YXJpYWJsZXMuIFNvIEkgZGVjaWRlZCB0byBjaG9vc2Ugb25seSB5ZWFycyBmcm9tIDIwMTggdG8gMjAyMC4gVGhlIHBsb3QgaGVscHMgdG8gaWRlbnRpZnkgdHJlbmRzIGFuZCBwYXR0ZXJucyBpbiBpbmNvbWUgZGlzdHJpYnV0aW9uIHJlbGF0aXZlIHRvIGhvdXNlaG9sZCBzaXplIGR1cmluZyB0aGVzZSB5ZWFycy4NClRoZSBmYWNldCB3cmFwIGFsbG93cyBmb3IgYSBjb21wYXJhdGl2ZSB2aWV3IG9mIGluY29tZSB0cmVuZHMgYWNyb3NzIHRoZSBzcGVjaWZpZWQgeWVhcnMsIGhlbHBpbmcgdG8gaWRlbnRpZnkgYW55IHNpZ25pZmljYW50IGNoYW5nZXMgb3IgY29uc2lzdGVudCBwYXR0ZXJucy4NCg0KX19NYWluIG9ic2VydmF0aW9uczpfXw0KDQpUaGUgYW5hbHlzaXMgb2YgdGhlIGF2ZXJhZ2UgbW9udGhseSBob3VzZWhvbGQgaW5jb21lIGluIHJlbGF0aW9uIHRvIHRoZSBudW1iZXIgb2YgaG91c2Vob2xkIG1lbWJlcnMgZnJvbSAyMDE4IHRvIDIwMjAgcmV2ZWFscyBzZXZlcmFsIGludGVyZXN0aW5nIHRyZW5kcy4gVGhlIGRhdGEgc2hvd3MgdGhhdCBob3VzZWhvbGQgaW5jb21lIGluY3JlYXNlcyBhcyB0aGUgbnVtYmVyIG9mIGZhbWlseSBtZW1iZXJzIGdyb3dzLCBidXQgdGhpcyB0cmVuZCBvbmx5IGhvbGRzIHVwIHRvIGEgY2VydGFpbiBwb2ludC4gU3BlY2lmaWNhbGx5LCB0aGUgYXZlcmFnZSBpbmNvbWUgcmlzZXMgc3RlYWRpbHkgd2l0aCBob3VzZWhvbGQgc2l6ZSB1bnRpbCBpdCByZWFjaGVzIGZpdmUgbWVtYmVycy4gQmV5b25kIHRoaXMgdGhyZXNob2xkLCB0aGUgaW5jb21lIGJlZ2lucyB0byBkZWNsaW5lIGdyYWR1YWxseSwgc3VnZ2VzdGluZyB0aGF0IGFkZGl0aW9uYWwgZmFtaWx5IG1lbWJlcnMgbWF5IGxlYWQgdG8gZGltaW5pc2hpbmcgZmluYW5jaWFsIHJldHVybnMsIHBvc3NpYmx5IGR1ZSB0byBpbmNyZWFzZWQgbGl2aW5nIGNvc3RzIG9yIHJlc291cmNlIGFsbG9jYXRpb24gY2hhbGxlbmdlcy4NCg0KSG93ZXZlciwgdGhlIHRyZW5kIHRha2VzIGEgc3VycHJpc2luZyB0dXJuIHdoZW4gdGhlIG51bWJlciBvZiBob3VzZWhvbGQgbWVtYmVycyBleGNlZWRzIG5pbmUuIEF0IHRoaXMgcG9pbnQsIHRoZXJlIGlzIGEgc2hhcnAgaW5jcmVhc2UgaW4gYXZlcmFnZSBob3VzZWhvbGQgaW5jb21lLCB3aGljaCBjb3VsZCBpbmRpY2F0ZSB0aGUgcHJlc2VuY2Ugb2YgYWRkaXRpb25hbCBpbmNvbWUgZWFybmVycyBpbiBsYXJnZXIgaG91c2Vob2xkcyBvciBlY29ub21pZXMgb2Ygc2NhbGUgdGhhdCBiZW5lZml0IHZlcnkgbGFyZ2UgZmFtaWxpZXMuIEZvbGxvd2luZyB0aGlzIHVuZXhwZWN0ZWQgc3Bpa2UsIHRoZSBpbmNvbWUgZHJvcHMgc2hhcnBseSBhZ2FpbiwgaGlnaGxpZ2h0aW5nIHBvdGVudGlhbCB2b2xhdGlsaXR5IGFuZCBmaW5hbmNpYWwgc3RyYWluIGluIGV4dHJlbWVseSBsYXJnZSBob3VzZWhvbGRzLg0KDQpUaGVzZSBmaW5kaW5ncyBzdWdnZXN0IHRoYXQgd2hpbGUgbGFyZ2VyIGhvdXNlaG9sZHMgbWF5IGJlbmVmaXQgZnJvbSBtdWx0aXBsZSBpbmNvbWUgc291cmNlcywgdGhleSBhbHNvIGZhY2UgaW5jcmVhc2VkIGZpbmFuY2lhbCBwcmVzc3VyZXMgdGhhdCBjYW4gaW1wYWN0IHRoZWlyIG92ZXJhbGwgZWNvbm9taWMgc3RhYmlsaXR5LiANCg0KPGNlbnRlcj4NCmBgYHtyIGhoX2luY29tZSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQojMQ0KaGdlbl9oaGluY19kYXRhIDwtIHJlYWRfZHRhKCJDOlxcUlxcZmluYWwgcHJvamVjdFxcZGF0YVxcaGdlbi5kdGEiLCBjb2xfc2VsZWN0ID0gYygiY2lkIiwgImhpZCIsICJzeWVhciIsICJoZ2hpbmMiKSkNCg0KaGdlbl9oaGluY19kYXRhIDwtIGhnZW5faGhpbmNfZGF0YSAlPiUNCiAgcmVuYW1lKA0KICAgIGBtb250aGx5X2hoaW5jYCA9IGhnaGluYw0KICApDQojMg0KcGxfaGhpbmNfZGF0YSA8LSByZWFkX2R0YSgiQzpcXFJcXGZpbmFsIHByb2plY3RcXGRhdGFcXHBsLmR0YSIsIGNvbF9zZWxlY3QgPSBjKCJjaWQiLCAiaGlkIiwgInBpZCIsICJzeWVhciIsICJwbGgwMTc1IikpDQoNCnBsX2hoaW5jX2RhdGEgPC0gcGxfaGhpbmNfZGF0YSAlPiUNCiAgcmVuYW1lKA0KICAgIGBoaGluY19zYXRgID0gcGxoMDE3NQ0KICApDQojMw0KcGVxdWl2X2hoc2l6ZV9kYXRhIDwtIHJlYWRfZHRhKCJDOlxcUlxcZmluYWwgcHJvamVjdFxcZGF0YVxccGVxdWl2LmR0YSIsIGNvbF9zZWxlY3QgPSBjKCJjaWQiLCAiaGlkIiwgInBpZCIsICJzeWVhciIsICJkMTExMDYiKSkNCg0KcGVxdWl2X2hoc2l6ZV9kYXRhIDwtIHBlcXVpdl9oaHNpemVfZGF0YSAlPiUNCiAgcmVuYW1lKA0KICAgIGBoaF9zaXplYCA9IGQxMTEwNiwNCiAgKQ0KDQpwbF9oZ2VuX3BlcXVpdl9oaGluYyA8LSBmdWxsX2pvaW4oaGdlbl9oaGluY19kYXRhLCBwbF9oaGluY19kYXRhLCBieSA9IGMoImhpZCIsICJzeWVhciIpKQ0KcGxfaGdlbl9wZXF1aXZfaGhpbmMgPC0gZnVsbF9qb2luKHBsX2hnZW5fcGVxdWl2X2hoaW5jLCBwZXF1aXZfaGhzaXplX2RhdGEsIGJ5ID0gYygiaGlkIiwgInN5ZWFyIikpDQoNCnBsX2hnZW5fcGVxdWl2X2hoaW5jIDwtIHBsX2hnZW5fcGVxdWl2X2hoaW5jICU+JQ0KICBtdXRhdGUoYWNyb3NzKGV2ZXJ5dGhpbmcoKSwgfiBhcy5udW1lcmljKGFzLmNoYXJhY3RlciguKSkpKQ0KDQpwbF9oZ2VuX3BlcXVpdl9oaGluYyA8LSBuYS5vbWl0KHBsX2hnZW5fcGVxdWl2X2hoaW5jKQ0KDQpwbF9oZ2VuX3BlcXVpdl9oaGluY19maWx0ZXIgPC0gcGxfaGdlbl9wZXF1aXZfaGhpbmMgJT4lIGZpbHRlcihoaGluY19zYXQgPj0gMCwgbW9udGhseV9oaGluYyA+PSAwLCBoaF9zaXplID49IDApIA0KDQpwbF9oZ2VuX3BlcXVpdl9oaGluY18xOF8yMCA8LSBwbF9oZ2VuX3BlcXVpdl9oaGluY19maWx0ZXIgJT4lIGZpbHRlcihzeWVhciA8PSAyMDIwICYgc3llYXIgPj0gMjAxOCkNCg0KZ2dwbG90KHBsX2hnZW5fcGVxdWl2X2hoaW5jXzE4XzIwLCBhZXMoeCA9IGhoX3NpemUsIHkgPSBtb250aGx5X2hoaW5jKSkgKw0KICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImxpbmUiLCBjb2xvciA9ICJjb3JuZmxvd2VyYmx1ZSIpICsgIA0KICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gInBvaW50IiwgY29sb3IgPSAiY29ybmZsb3dlcmJsdWUiKSArICAgDQogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBtb250aGx5IGhvdXNlaG9sZCBpbmNvbWUgZGVwZW5kaW5nIG9uIHRoZSBudW1iZXIgb2YgZmFtaWx5IG1lbWJlcnMiLA0KICAgICAgIHggPSAiTnVtYmVyIG9mIEhIIG1lbWJlcnMiLA0KICAgICAgIHkgPSAiTWVhbiBtb250aGx5IGluY29tZSBvZiBISCAoRVVSKSIpICsNCiAgZmFjZXRfd3JhcCh+IHN5ZWFyKSArIA0KICB0aGVtZV9taW5pbWFsKCkNCg0KYGBgDQo8L2NlbnRlcj4NCg0KDQojIyBBdmVyYWdlIEluY29tZSBQZXIgUGVyc29uIGluIGhvdXNlaG9sZA0KDQpUbyBmdXJ0aGVyIGFuYWx5emUgaG91c2Vob2xkIGluY29tZSBkeW5hbWljcywgSSBjYWxjdWxhdGVkIHRoZSBpbmNvbWUgcGVyIGhvdXNlaG9sZCBtZW1iZXIgdG8gdW5kZXJzdGFuZCB0aGUgYXZlcmFnZSBpbmNvbWUgcGVyIGluZGl2aWR1YWwgaW4gZWFjaCBob3VzZWhvbGQuIFRoaXMgY2FsY3VsYXRpb24gd2FzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoZSBhdmFpbGFibGUgZGF0YXNldCBkaWQgbm90IHByb3ZpZGUgYSB2YXJpYWJsZSBmb3IgbW9udGhseSBpbmRpdmlkdWFsIGluY29tZS4gQnkgZGVyaXZpbmcgdGhpcyBtZXRyaWMsIEkgY291bGQgbW9yZSBhY2N1cmF0ZWx5IGFzc2VzcyB0aGUgZmluYW5jaWFsIHNpdHVhdGlvbiBvbiBhIHBlci1wZXJzb24gYmFzaXMgd2l0aGluIGhvdXNlaG9sZHMuDQoNCl9fTWFpbiBvYnNlcnZhdGlvbnM6X18NCg0KVGhlIHJlc3VsdGluZyBwbG90IGRpc3BsYXlzIHRoZSB0cmVuZCBvZiBhdmVyYWdlIGluY29tZSBwZXIgcGVyc29uIGZyb20gMjAxOCB0byAyMDIwLiBUaGUgZ3JhcGggc2hvd3MgYSBncmFkdWFsIGluY3JlYXNlIGluIHRoZSBhdmVyYWdlIGluY29tZSBwZXIgcGVyc29uIG92ZXIgdGhlIHllYXJzLCBpbmRpY2F0aW5nIGFuIG92ZXJhbGwgaW1wcm92ZW1lbnQgaW4gaW5kaXZpZHVhbCBlY29ub21pYyBjb25kaXRpb25zIHdpdGhpbiBob3VzZWhvbGRzLiBUaGlzIHVwd2FyZCB0cmVuZCBzdWdnZXN0cyB0aGF0IGhvdXNlaG9sZCBpbmNvbWVzIGFyZSByaXNpbmcgaW4gYSB3YXkgdGhhdCBiZW5lZml0cyBlYWNoIG1lbWJlciBtb3JlIHNpZ25pZmljYW50bHkgb3ZlciB0aW1lLg0KDQpBIHBhcnRpY3VsYXJseSBub3RhYmxlIG9ic2VydmF0aW9uIGZyb20gdGhlIGdyYXBoIGlzIHRoZSBtYXJrZWQgaW5jcmVhc2UgaW4gcGVyIGNhcGl0YSBpbmNvbWUgaW4gMjAwMS4gVGhpcyBzaWduaWZpY2FudCBqdW1wIG1heSByZWZsZWN0IGJyb2FkZXIgZWNvbm9taWMgY2hhbmdlcywgcG9saWN5IGltcGFjdHMsIG9yIHNoaWZ0cyBpbiB0aGUgbGFib3IgbWFya2V0IHRoYXQgcGFydGljdWxhcmx5IGJlbmVmaXR0ZWQgaG91c2Vob2xkcyBkdXJpbmcgdGhhdCB5ZWFyLiANCg0KPGNlbnRlcj4NCmBgYHtyIHBfaW5jb21lLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCiMxDQpoZ2VuX2hoaW5jX2RhdGEgPC0gcmVhZF9kdGEoIkM6L1IvZmluYWwgcHJvamVjdC9kYXRhL2hnZW4uZHRhIiwgY29sX3NlbGVjdCA9IGMoImNpZCIsICJoaWQiLCAic3llYXIiLCAiaGdoaW5jIikpDQoNCmhnZW5faGhpbmNfZGF0YSA8LSBoZ2VuX2hoaW5jX2RhdGEgJT4lDQogIHJlbmFtZSgNCiAgICBgbW9udGhseV9oaGluY2AgPSBoZ2hpbmMNCiAgKQ0KDQojMg0KcGVxdWl2X2hoc2l6ZV9kYXRhIDwtIHJlYWRfZHRhKCJDOi9SL2ZpbmFsIHByb2plY3QvZGF0YS9wZXF1aXYuZHRhIiwgY29sX3NlbGVjdCA9IGMoImNpZCIsICJoaWQiLCAicGlkIiwgInN5ZWFyIiwgImQxMTEwNiIpKQ0KDQpwZXF1aXZfaGhzaXplX2RhdGEgPC0gcGVxdWl2X2hoc2l6ZV9kYXRhICU+JQ0KICByZW5hbWUoDQogICAgYGhoX3NpemVgID0gZDExMTA2DQogICkNCmhnZW5fcGVxdWl2X2hoaW5jIDwtIGZ1bGxfam9pbihoZ2VuX2hoaW5jX2RhdGEsIHBlcXVpdl9oaHNpemVfZGF0YSwgYnkgPSBjKCJoaWQiLCAic3llYXIiKSkNCg0KDQpoZ2VuX3BlcXVpdl9oaGluYyA8LSBoZ2VuX3BlcXVpdl9oaGluYyAlPiUNCiAgbXV0YXRlKGFjcm9zcyhldmVyeXRoaW5nKCksIH4gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoLikpKSkNCg0KaGdlbl9wZXF1aXZfaGhpbmMgPC0gbmEub21pdChoZ2VuX3BlcXVpdl9oaGluYykNCg0KaGdlbl9wZXF1aXZfaGhpbmNfZmlsdGVyIDwtIGhnZW5fcGVxdWl2X2hoaW5jICU+JSBmaWx0ZXIoIG1vbnRobHlfaGhpbmMgPj0gMCwgaGhfc2l6ZSA+PSAwKSANCg0KaGdlbl9wZXF1aXZfaGhpbmNfZmlsdGVyIDwtIGhnZW5fcGVxdWl2X2hoaW5jX2ZpbHRlciAlPiUNCiAgbXV0YXRlKA0KICAgIGluY29tZV9wZXJfcGVyc29uID0gbW9udGhseV9oaGluYyAvIGhoX3NpemUNCiAgKQ0KDQoNCmluY29tZV9wZXJfcGVyc29uX2J5X3llYXIgPC0gaGdlbl9wZXF1aXZfaGhpbmNfZmlsdGVyICU+JQ0KICBncm91cF9ieShzeWVhcikgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBpbmNvbWVfcGVyX3BlcnNvbl9ieV95ZWFyID0gbWVhbihpbmNvbWVfcGVyX3BlcnNvbiwgbmEucm0gPSBUUlVFKQ0KICApDQoNCmdncGxvdChpbmNvbWVfcGVyX3BlcnNvbl9ieV95ZWFyLCBhZXMoeCA9IHN5ZWFyLCB5ID0gaW5jb21lX3Blcl9wZXJzb25fYnlfeWVhcikpICsgDQogIGdlb21fbGluZShjb2xvciA9ICJtZWRpdW1zZWFncmVlbiIsIGxpbmV3aWR0aCA9IDAuMikgKyANCiAgZ2VvbV9wb2ludChjb2xvciA9ICJtZWRpdW1zZWFncmVlbiIsIHNpemUgPSAyKSArIA0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgSW5jb21lIFBlciBQZXJzb24gaW4gSEggYnkgWWVhciIsDQogICAgICAgeCA9ICJZZWFyIiwNCiAgICAgICB5ID0gIkF2ZXJhZ2UgSW5jb21lIFBlciBQZXJzb24gKEVVUikiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQo8L2NlbnRlcj4NCg0KIyBFZHVjYXRpb24gYW5kIEVtcGxveW1lbnQgey50YWJzZXR9DQoNCkVkdWNhdGlvbiBnZW5lcmFsbHkgY29udHJpYnV0ZXMgdG8gaGlnaGVyIGhhcHBpbmVzcyB0aHJvdWdoIGltcHJvdmVkIGZpbmFuY2lhbCBzdGFiaWxpdHksIGJldHRlciBoZWFsdGgsIGFuZCBlbmhhbmNlZCBzb2NpYWwgYW5kIHBzeWNob2xvZ2ljYWwgYmVuZWZpdHMuIEl0IG9mdGVuIGxlYWRzIHRvIGdyZWF0ZXIgam9iIHNhdGlzZmFjdGlvbiBhbmQgYSBzZW5zZSBvZiBhY2hpZXZlbWVudC4NCg0KRWR1Y2F0aW9uIHBsYXlzIGEgY3J1Y2lhbCByb2xlIGluIHNoYXBpbmcgYW4gaW5kaXZpZHVhbCdzIGxpZmUgb3Bwb3J0dW5pdGllcyBhbmQgb3ZlcmFsbCB3ZWxsLWJlaW5nLiBUaGlzIHBhcnQgZXhwbG9yZXMgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQgYW5kIGVtcGxveW1lbnQgc3RhdHVzLCBhcyB3ZWxsIGFzIHRoZWlyIGNvbWJpbmVkIGltcGFjdCBvbiBsaWZlIHNhdGlzZmFjdGlvbi4NCg0KIyMgQXZlcmFnZSBZZWFycyBvZiBFZHVjYXRpb24gYnkgWWVhcg0KDQpUaGUgZ3JhcGggaWxsdXN0cmF0ZXMgdGhlIHRyZW5kIGluIGF2ZXJhZ2UgeWVhcnMgb2YgZWR1Y2F0aW9uIGZyb20gMTk4NCB0byAyMDIwLg0KDQpfX01haW4gb2JzZXJ2YXRpb25zOl9fDQoNClRoZSBncmFwaCBzaG93cyBhIGNsZWFyIHVwd2FyZCB0cmVuZCBpbiB0aGUgYXZlcmFnZSB5ZWFycyBvZiBlZHVjYXRpb24gZnJvbSAxOTgwIHRvIGFyb3VuZCAyMDEwLCAgZm9sbG93ZWQgYnkgZmx1Y3R1YXRpb25zIGluIHRoZSBzdWJzZXF1ZW50IHllYXJzLiBUaGlzIGluZGljYXRlcyBhIGdlbmVyYWwgaW5jcmVhc2UgaW4gdGhlIG51bWJlciBvZiB5ZWFycyBpbmRpdmlkdWFscyBzcGVuZCBpbiBlZHVjYXRpb24gb3ZlciB0aGUgNDAteWVhciBwZXJpb2QuDQoNCg0KPGNlbnRlcj4NCmBgYHtyIGVkdV95ZWFycywgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQpwZXF1aXZfZWR1X2RhdGEgPC0gcmVhZF9kdGEoIkM6L1IvZmluYWwgcHJvamVjdC9kYXRhL3BlcXVpdi5kdGEiLCBjb2xfc2VsZWN0ID0gYygiY2lkIiwgImhpZCIsICJwaWQiLCAic3llYXIiLCAiZDExMTA4IiwgImQxMTEwOSIpKQ0KDQpwZXF1aXZfZWR1X2RhdGEgPC0gcGVxdWl2X2VkdV9kYXRhICU+JQ0KICByZW5hbWUoDQogICAgYGVkdWNhdGlvbl9IU2AgPSBkMTExMDgsDQogICAgYHllYXJzX29mX0VkdWNhdGlvbmAgPSBkMTExMDkNCiAgKQ0KDQpwZXF1aXZfZWR1X2RhdGFfZmlsdGVyIDwtIHBlcXVpdl9lZHVfZGF0YSAlPiUNCiAgbXV0YXRlKGVkdWNhdGlvbl9IUyA9IGFzLm51bWVyaWMoZWR1Y2F0aW9uX0hTKSwgeWVhcnNfb2ZfRWR1Y2F0aW9uID0gYXMubnVtZXJpYyh5ZWFyc19vZl9FZHVjYXRpb24pKSAlPiUNCiAgZmlsdGVyKHllYXJzX29mX0VkdWNhdGlvbiA+IDAsIGVkdWNhdGlvbl9IUyA+IDApDQoNCmF2ZXJhZ2VfeWVhcnNfb2ZfZWR1Y2F0aW9uX2J5X3llYXIgPC0gcGVxdWl2X2VkdV9kYXRhX2ZpbHRlciAlPiUNCiAgZ3JvdXBfYnkoc3llYXIpICU+JQ0KICBzdW1tYXJpemUoTWVhbl9ZZWFyc19vZl9FZHVjYXRpb24gPSBtZWFuKHllYXJzX29mX0VkdWNhdGlvbiwgbmEucm0gPSBUUlVFKSkNCg0KIyAzNDksMDcwIGVudHJpZXMNCmdncGxvdChhdmVyYWdlX3llYXJzX29mX2VkdWNhdGlvbl9ieV95ZWFyLCBhZXMoeCA9IHN5ZWFyLCB5ID0gTWVhbl9ZZWFyc19vZl9FZHVjYXRpb24pKSArDQogIGdlb21fbGluZShjb2xvciA9ICJtZWRpdW1zZWFncmVlbiIsIGxpbmV3aWR0aCA9IDAuMikgKyAgDQogIGdlb21fcG9pbnQoY29sb3IgPSAibWVkaXVtc2VhZ3JlZW4iLCBzaXplID0gMikgKyAgIA0KICBsYWJzKHRpdGxlID0gIkF2ZXJhZ2UgWWVhcnMgb2YgRWR1Y2F0aW9uIGJ5IFllYXIiLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJBdmVyYWdlIFllYXJzIG9mIEVkdWNhdGlvbiIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KPC9jZW50ZXI+DQoNCiMjIEF2ZXJhZ2UgWWVhcnMgb2YgRWR1Y2F0aW9uIGJ5IFllYXIgYW5kIEVkdWNhdGlvbiBMZXZlbA0KDQpUaGUgZmFjZXRlZCBwbG90IGhpZ2hsaWdodHMgZGlzdGluY3QgdHJlbmRzIGZvciBlYWNoIGVkdWNhdGlvbmFsIGxldmVsLCBlbXBoYXNpemluZyB0aGUgZGlmZmVyZW50IHRyYWplY3RvcmllcyBhbmQgZ3Jvd3RoIHBhdHRlcm5zLg0KDQpfX01haW4gb2JzZXJ2YXRpb25zOl9fDQoNCkZvciBfX18iTGVzcyB0aGFuIEhTLCJfX18gdGhlcmUgaXMgYSBub3RpY2VhYmxlIGluY3JlYXNlIGZvbGxvd2VkIGJ5IHN0YWJpbGl6YXRpb24sIGluZGljYXRpbmcgZWZmb3J0cyB0byBlbmhhbmNlIGJhc2ljIGVkdWNhdGlvbiBhY2Nlc3MuDQoNClRoZSBfX18iSGlnaCBTY2hvb2wiX19fIGNhdGVnb3J5IHNob3dzIGNvbnNpc3RlbnQgZ3Jvd3RoLCByZWZsZWN0aW5nIGluY3JlYXNlZCByZXRlbnRpb24gYW5kIGNvbXBsZXRpb24gcmF0ZXMuDQoNClRoZSBfX18iTW9yZSB0aGFuIEhTIl9fXyBjYXRlZ29yeSBzaG93cyBhIHByb25vdW5jZWQgdXB3YXJkIHRyZW5kLCBlbXBoYXNpemluZyB0aGUgZ3Jvd2luZyBkZW1hbmQgZm9yIGFkdmFuY2VkIGVkdWNhdGlvbiBhbmQgcHJvZmVzc2lvbmFsIHF1YWxpZmljYXRpb25zLg0KDQpUaGUgZ2FwIGJldHdlZW4gdGhlIGF2ZXJhZ2UgeWVhcnMgb2YgZWR1Y2F0aW9uIGZvciB0aG9zZSB3aXRoICJNb3JlIHRoYW4gSFMiIGFuZCB0aG9zZSB3aXRoIG9ubHkgIkhpZ2ggU2Nob29sIiBlZHVjYXRpb24gaGFzIHdpZGVuZWQgb3ZlciB0aW1lLiBUaGlzIHN1Z2dlc3RzIGluY3JlYXNpbmcgc3RyYXRpZmljYXRpb24gYmFzZWQgb24gZWR1Y2F0aW9uYWwgYXR0YWlubWVudCwgd2hpY2ggY291bGQgaGF2ZSBpbXBsaWNhdGlvbnMgZm9yIGluY29tZSBpbmVxdWFsaXR5LCBlbXBsb3ltZW50IG9wcG9ydHVuaXRpZXMsIGFuZCBzb2NpYWwgbW9iaWxpdHkuDQoNCjxjZW50ZXI+DQpgYGB7ciB5ZWFyc19sZXZlbF9lZHUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KDQphdmVyYWdlX2VkdWNhdGlvbl9IU19ieV95ZWFyIDwtIHBlcXVpdl9lZHVfZGF0YV9maWx0ZXIgJT4lDQogIGdyb3VwX2J5KHN5ZWFyLCBlZHVjYXRpb25fSFMpICU+JQ0KICBzdW1tYXJpemUoTWVhbl9ZZWFyc19vZl9FZHVjYXRpb24gPSBtZWFuKHllYXJzX29mX0VkdWNhdGlvbiwgbmEucm0gPSBUUlVFKSkNCg0KZ2dwbG90KGF2ZXJhZ2VfZWR1Y2F0aW9uX0hTX2J5X3llYXIsIGFlcyh4ID0gc3llYXIsIHkgPSBNZWFuX1llYXJzX29mX0VkdWNhdGlvbiwgY29sb3IgPSBhcy5mYWN0b3IoZWR1Y2F0aW9uX0hTKSkpICsNCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDAuMikgKw0KICBnZW9tX3BvaW50KHNpemUgPSAxLjEpICsNCiAgbGFicyh0aXRsZSA9ICJBdmVyYWdlIFllYXJzIG9mIEVkdWNhdGlvbiBieSBZZWFyIGFuZCBFZHVjYXRpb24gTGV2ZWwiLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJBdmVyYWdlIFllYXJzIG9mIEVkdWNhdGlvbiIsDQogICAgICAgY29sb3IgPSAiRWR1Y2F0aW9uIExldmVsIikgKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiMSIgPSAidG9tYXRvIiwgIjIiID0gIm1lZGl1bXNlYWdyZWVuIiwgIjMiID0gImNvcm5mbG93ZXJibHVlIiksDQogICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxIiA9ICJMZXNzIHRoYW4gSFMiLCAiMiIgPSAiSGlnaCBTY2hvb2wiLCAiMyIgPSAiTW9yZSB0aGFuIEhTIikpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCmBgYA0KPC9jZW50ZXI+DQoNClRoaXMgaXMgYSBfZmFjZXRlZCBwbG90Xywgd2hpY2ggZGl2aWRlcyB0aGUgZGF0YSBpbnRvIHRocmVlIHBhbmVscywgZWFjaCBjb3JyZXNwb25kaW5nIHRvIG9uZSBvZiB0aGUgZWR1Y2F0aW9uYWwgbGV2ZWxzLCBhbGxvd2luZyBmb3IgYSBkZXRhaWxlZCBleGFtaW5hdGlvbiBvZiB0cmVuZHMgd2l0aGluIGVhY2ggY2F0ZWdvcnkgb3ZlciB0aGUgc3BlY2lmaWVkIHllYXJzLg0KDQo8Y2VudGVyPg0KYGBge3IgeWVhcnNfbGV2ZWxfZWR1XzIsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KZ2dwbG90KGF2ZXJhZ2VfZWR1Y2F0aW9uX0hTX2J5X3llYXIsIGFlcyh4ID0gc3llYXIsIHkgPSBNZWFuX1llYXJzX29mX0VkdWNhdGlvbikpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gIm1lZGl1bXNlYWdyZWVuIiwgbGluZXdpZHRoID0gMC4yKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAibWVkaXVtc2VhZ3JlZW4iLCBzaXplID0gMS4xKSArDQogIGxhYnModGl0bGUgPSAiQXZlcmFnZSBZZWFycyBvZiBFZHVjYXRpb24gYnkgWWVhciBhbmQgRWR1Y2F0aW9uIExldmVsIiwNCiAgICAgICB4ID0gIlllYXIiLA0KICAgICAgIHkgPSAiQXZlcmFnZSBZZWFycyBvZiBFZHVjYXRpb24iKSArDQogIGZhY2V0X3dyYXAofiBlZHVjYXRpb25fSFMsIHNjYWxlcyA9ICJmcmVlX3kiLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKGMoDQogICAgYDFgID0gIkxlc3MgdGhhbiBIUyIsDQogICAgYDJgID0gIkhpZ2ggU2Nob29sIiwNCiAgICBgM2AgPSAiTW9yZSB0aGFuIEhTIg0KICApKSkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KPC9jZW50ZXI+DQoNCiMjIEVkdWNhdGlvbiBhbmQgZW1wbG95bWVudCBzdGF0dXMNCg0KVGhpcyBpcyBhIHZpb2xpbiBwbG90IHNob3dpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiB5ZWFycyBvZiBlZHVjYXRpb24gYWNyb3NzIGRpZmZlcmVudCBlbXBsb3ltZW50IHN0YXR1c2VzLCBjb25zaWRlcmVkIGluIF9fX3BnZW4uZHRhX19fLg0KDQoNCl9fTWFpbiBvYnNlcnZhdGlvbnM6X18NCg0KICAxLiAqRnVsbC1UaW1lIEVtcGxveW1lbnQqOiBJbmRpdmlkdWFscyB3aXRoIGZ1bGwtdGltZSBlbXBsb3ltZW50IGdlbmVyYWxseSBoYXZlIGEgaGlnaGVyIGxldmVsIG9mIGVkdWNhdGlvbi4gVGhlIHBsb3QgaXMgbW9yZSBjb25jZW50cmF0ZWQgYXJvdW5kIGhpZ2hlciB5ZWFycyBvZiBlZHVjYXRpb24sIHdpdGggYSBub3RhYmxlIHBlYWsgYXQgYXJvdW5kIDE1IHllYXJzLCBpbmRpY2F0aW5nIHRoYXQgbWFueSBpbmRpdmlkdWFscyBpbiB0aGlzIGNhdGVnb3J5IGhhdmUgc29tZSBjb2xsZWdlIGVkdWNhdGlvbiBvciBoaWdoZXIuDQogIA0KICAyLiAqUmVndWxhciBQYXJ0LVRpbWUgYW5kIFZvY2F0aW9uYWwgVHJhaW5pbmcqOiBUaGVzZSBncm91cHMgc2hvdyBzaW1pbGFyIHBhdHRlcm5zLCB3aXRoIGEgc2xpZ2h0IHBlYWsgYXJvdW5kIDEyLTE1IHllYXJzIG9mIGVkdWNhdGlvbi4gVGhpcyBzdWdnZXN0cyB0aGF0IG1hbnkgaW5kaXZpZHVhbHMgaW4gdGhlc2UgY2F0ZWdvcmllcyBoYXZlIGNvbXBsZXRlZCBoaWdoIHNjaG9vbCBhbmQgc29tZSBoYXZlIGF0dGVuZGVkIGNvbGxlZ2Ugb3Igdm9jYXRpb25hbCB0cmFpbmluZyBwcm9ncmFtcy4NCiAgDQogIDMuICpNYXJnaW5hbC9JcnJlZ3VsYXIgUGFydC1UaW1lIGFuZCBOb3QgRW1wbG95ZWQqOiBUaGVzZSBncm91cHMgaGF2ZSBhIGJyb2FkZXIgZGlzdHJpYnV0aW9uIG9mIHllYXJzIG9mIGVkdWNhdGlvbiwgd2l0aCBtYW55IGluZGl2aWR1YWxzIGhhdmluZyBsZXNzIHRoYW4gYSBoaWdoIHNjaG9vbCBlZHVjYXRpb24gYW5kIG90aGVycyBoYXZpbmcgbW9yZS4gVGhpcyBzcHJlYWQgaW5kaWNhdGVzIGEgd2lkZSByYW5nZSBvZiBlZHVjYXRpb25hbCBiYWNrZ3JvdW5kcyBhbW9uZyB0aGVzZSBpbmRpdmlkdWFscy4NCiAgDQogIDQuICpTaGVsdGVyZWQgV29ya3Nob3AqOiBUaGlzIGdyb3VwIHNob3dzIGEgdW5pcXVlIGRpc3RyaWJ1dGlvbiwgd2l0aCBtb3N0IGluZGl2aWR1YWxzIGhhdmluZyBmZXdlciB5ZWFycyBvZiBlZHVjYXRpb24sIHR5cGljYWxseSBsZXNzIHRoYW4gaGlnaCBzY2hvb2wuDQoNCmBgYHtyIGVkdV9lbXBsLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCnBlcXVpdl9lZHUgPC0gcmVhZF9kdGEoIkM6L1IvZmluYWwgcHJvamVjdC9kYXRhL3BlcXVpdi5kdGEiLCBjb2xfc2VsZWN0ID0gYygiY2lkIiwgImhpZCIsICJwaWQiLCAic3llYXIiLCAiZDExMTA5IikpDQoNCnBlcXVpdl9lZHUgPC0gcGVxdWl2X2VkdSAlPiUNCiAgcmVuYW1lKA0KICAgIGB5ZWFyc19vZl9FZHVjYXRpb25gID0gZDExMTA5DQogICkNCg0KcGdlbl9lbXBsIDwtIHJlYWRfZHRhKCJDOi9SL2ZpbmFsIHByb2plY3QvZGF0YS9wZ2VuLmR0YSIsIGNvbF9zZWxlY3QgPSBjKCJjaWQiLCAiaGlkIiwgInBpZCIsICJzeWVhciIsICJwZ2VtcGxzdCIpKQ0KDQpwZXF1aXZfcGdlbl9lZHUgPC0gZnVsbF9qb2luKHBlcXVpdl9lZHUsIHBnZW5fZW1wbCwgYnkgPSBjKCJwaWQiLCAiaGlkIiwgImNpZCIsICJzeWVhciIpKQ0KDQpwZXF1aXZfcGdlbl9lZHUgPC0gbmEub21pdChwZXF1aXZfcGdlbl9lZHUpICU+JSANCiAgZmlsdGVyKHllYXJzX29mX0VkdWNhdGlvbiA+PSAwLCBwZ2VtcGxzdCA+PSAwKQ0KDQpwZXF1aXZfcGdlbl9lZHUgPC0gcGVxdWl2X3BnZW5fZWR1ICU+JQ0KICBtdXRhdGUocGdlbXBsc3QgPSBmYWN0b3IocGdlbXBsc3QsIGxldmVscyA9IDE6NiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJGdWxsLVRpbWUgRW1wbG95bWVudCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVndWxhciBQYXJ0LVRpbWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlZvY2F0aW9uYWwgVHJhaW5pbmciLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1hcmdpbmFsL0lycmVndWxhciBQYXJ0LVRpbWUiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vdCBFbXBsb3llZCIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2hlbHRlcmVkIFdvcmtzaG9wIikpKQ0KDQpnZ3Bsb3QocGVxdWl2X3BnZW5fZWR1LCBhZXMoeCA9IHBnZW1wbHN0LCB5ID0geWVhcnNfb2ZfRWR1Y2F0aW9uKSkgKw0KICBnZW9tX3Zpb2xpbihmaWxsID0gInRvbWF0byIsIGNvbG9yID0gImJsYWNrIiwgYWxwaGEgPSAwLjcpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJZZWFycyBvZiBFZHVjYXRpb24gYnkgRW1wbG95bWVudCBTdGF0dXMiLA0KICAgIHggPSAiRW1wbG95bWVudCBTdGF0dXMiLA0KICAgIHkgPSAiWWVhcnMgb2YgRWR1Y2F0aW9uIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQojIyBMaWZlIHNhdGlzZmFjdGlvbiBhbmQgZW1wbG95bWVudCBzdGF0dXMNCg0KVGhpcyBib3ggcGxvdCBzaG93aW5nIHRoZSBkaXN0cmlidXRpb24gb2YgbGlmZSBzYXRpc2ZhY3Rpb24gc2NvcmVzIChvbiBhIHNjYWxlIGZyb20gMCB0byAxMCkgYWNyb3NzIHRoZSBzYW1lIGVtcGxveW1lbnQgc3RhdHVzZXMuIA0KDQpfX01haW4gb2JzZXJ2YXRpb25zOl9fDQoNCl9fTm90IEVtcGxveWVkIGFuZCBTaGVsdGVyZWQgV29ya3Nob3AgZ3JvdXBzX18gZ2VuZXJhbGx5IHJlcG9ydCBsb3dlciBsaWZlIHNhdGlzZmFjdGlvbiwgd2l0aCBtZWRpYW4gc2NvcmVzIHNsaWdodGx5IGxvd2VyIHRoYW4gdGhlIGVtcGxveWVkIGdyb3Vwcy4gVGhlIHJhbmdlIG9mIHNjb3JlcyBpcyB3aWRlciwgc3VnZ2VzdGluZyBncmVhdGVyIHZhcmlhYmlsaXR5IGluIGxpZmUgc2F0aXNmYWN0aW9uIGFtb25nIGluZGl2aWR1YWxzIHdobyBhcmUgbm90IGVtcGxveWVkIG9yIGluIHNoZWx0ZXJlZCB3b3Jrc2hvcHMuIFNvbWUgaW5kaXZpZHVhbHMgcmVwb3J0IGhpZ2ggbGlmZSBzYXRpc2ZhY3Rpb24sIHdoaWxlIG90aGVycyByZXBvcnQgdmVyeSBsb3cgc2F0aXNmYWN0aW9uLg0KDQpUaGUgZ2FwIGluIGVkdWNhdGlvbiBsZXZlbHMgYmV0d2VlbiBkaWZmZXJlbnQgZW1wbG95bWVudCBjYXRlZ29yaWVzIChlLmcuLCBmdWxsLXRpbWUgdnMuIG5vdCBlbXBsb3llZCkgc3VnZ2VzdHMgYSBzdHJhdGlmaWNhdGlvbiBpbiBlbXBsb3ltZW50IG9wcG9ydHVuaXRpZXMgYmFzZWQgb24gZWR1Y2F0aW9uYWwgYXR0YWlubWVudC4gVGhvc2Ugd2l0aCBoaWdoZXIgZWR1Y2F0aW9uIGxldmVscyBhcmUgbW9yZSBsaWtlbHkgdG8gc2VjdXJlIHN0YWJsZSBlbXBsb3ltZW50LCB3aGljaCBpcyBhc3NvY2lhdGVkIHdpdGggaGlnaGVyIGxpZmUgc2F0aXNmYWN0aW9uLg0KDQoNCjxjZW50ZXI+DQpgYGB7ciBlbXBsX2xpZmVzYXQsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KcGVxdWl2X2NvbSA8LSByZWFkX2R0YSgiQzovUi9maW5hbCBwcm9qZWN0L2RhdGEvcGVxdWl2LmR0YSIsIGNvbF9zZWxlY3QgPSBjKCJjaWQiLCAiaGlkIiwgInBpZCIsICJzeWVhciIsICJwMTExMDEiKSkNCg0KcGVxdWl2X2NvbSA8LSBwZXF1aXZfY29tICU+JSBmaWx0ZXJfYWxsKGFsbF92YXJzKC4gPj0gMCkpICU+JQ0KICByZW5hbWUoDQogICAgYGxpZmVzYXRgID0gcDExMTAxDQogICkNCg0KIzM4MTkxNw0KcGdlbl9wZXF1aXZfam9iIDwtIGZ1bGxfam9pbihwZ2VuX2VtcGwsIHBlcXVpdl9jb20sIGJ5ID0gYygicGlkIiwgImhpZCIsICJjaWQiLCAic3llYXIiKSkNCg0KIzM2Mzk3OA0KcGdlbl9wZXF1aXZfam9iIDwtIG5hLm9taXQocGdlbl9wZXF1aXZfam9iKSAlPiUgDQogIGZpbHRlcihwZ2VtcGxzdCA+PSAwLCBsaWZlc2F0ID49IDApDQoNCg0KcGdlbl9wZXF1aXZfam9iIDwtIHBnZW5fcGVxdWl2X2pvYiAlPiUNCiAgbXV0YXRlKHBnZW1wbHN0ID0gZmFjdG9yKHBnZW1wbHN0LCBsZXZlbHMgPSAxOjYsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiRnVsbC1UaW1lIEVtcGxveW1lbnQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJlZ3VsYXIgUGFydC1UaW1lIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJWb2NhdGlvbmFsIFRyYWluaW5nIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNYXJnaW5hbC9JcnJlZ3VsYXIgUGFydC1UaW1lIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3QgRW1wbG95ZWQiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNoZWx0ZXJlZCBXb3Jrc2hvcCIpKSkNCg0KIyBCb3hwbG90IG9mIGxpZmUgc2F0aXNmYWN0aW9uIGJ5IGVtcGxveW1lbnQgc3RhdHVzDQpnZ3Bsb3QocGdlbl9wZXF1aXZfam9iLCBhZXMoeCA9IHBnZW1wbHN0LCB5ID0gbGlmZXNhdCkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAiY29ybmZsb3dlcmJsdWUiLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC43KSArDQogIGxhYnMoDQogICAgdGl0bGUgPSAiTGlmZSBTYXRpc2ZhY3Rpb24gYnkgRW1wbG95bWVudCBTdGF0dXMgKDE5ODQtMjAyMCkiLA0KICAgIHggPSAiRW1wbG95bWVudCBTdGF0dXMiLA0KICAgIHkgPSAiTGlmZSBTYXRpc2ZhY3Rpb24gKDAtMTApIg0KICApICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KPC9jZW50ZXI+DQoNCg0KDQojIENvbW11dGluZyB7LnRhYnNldH0NCg0KVGhpcyBzZWN0aW9uIGV4cGxvcmVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBjb21tdXRpbmcgcGF0dGVybnMgYW5kIG92ZXJhbGwgbGlmZSBzYXRpc2ZhY3Rpb24uIEJ5IGV4YW1pbmluZyB2YXJpb3VzIG1ldHJpY3Mgc3VjaCBhcyBjb21tdXRpbmcgZGlzdGFuY2UsIHRpbWUsIGFuZCBmcmVxdWVuY3kgb3ZlciBkaWZmZXJlbnQgeWVhcnMsIHdlIGNhbiBnYWluIGEgZGVlcGVyIHVuZGVyc3RhbmRpbmcgb2YgaG93IGNoYW5nZXMgaW4gY29tbXV0aW5nIGJlaGF2aW9yIG1pZ2h0IGluZmx1ZW5jZSBoYXBwaW5lc3MuDQoNCiMjIE1lYW4gQ29tbXV0aW5nIERpc3RhbmNlIGFuZCBNZWFuIENvbW11dGluZyBUaW1lDQoNClRoZSBiYXIgcGxvdCBjb21wYXJlcyB0d28gZGlmZmVyZW50IG1ldHJpY3Mgb3ZlciBzZXZlcmFsIHllYXJzOiBNZWFuIENvbW11dGluZyBEaXN0YW5jZSAoaW4ga2lsb21ldGVycykgYW5kIE1lYW4gQ29tbXV0aW5nIFRpbWUgKGluIG1pbnV0ZXMpLiBFYWNoIGJhciByZXByZXNlbnRzIGEgZGlmZmVyZW50IHllYXIsIHNob3dpbmcgYm90aCBtZXRyaWNzIG9uIHRoZSBzYW1lIGdyYXBoIHVzaW5nIHR3byBkaWZmZXJlbnQgc2NhbGVzLg0KDQpfX01haW4gb2JzZXJ2YXRpb25zOl9fDQoNCk92ZXIgdGhlIHllYXJzIHNob3duICgyMDE1LCAyMDE3LCAyMDE5IGFuZCAyMDIxKSwgd2Ugc2VlIHZhcmlhdGlvbnMgaW4gYm90aCBjb21tdXRpbmcgZGlzdGFuY2UgYW5kIHRpbWUuDQpGb3IgaW5zdGFuY2UsIHRoZSBtZWFuIGNvbW11dGluZyBkaXN0YW5jZSBpbmNyZWFzZWQgZnJvbSAyMDE1IHRvIDIwMTcgYW5kIHN0YXJ0ZWQgc2xpZ2h0bHkgZGVjcmVhc2luZyBhZnRlciwgd2hpbGUgdGhlIG1lYW4gY29tbXV0aW5nIHRpbWUgcmVtYWluZWQgYWxtb3N0IGNvbnN0YW50IGFjcm9zcyB0aGVzZSB5ZWFycy4NCg0KU2luY2UgMjAxNywgY29tbXV0aW5nIGhhcyBkZWNyZWFzZWQsIGxpa2VseSBkdWUgdG8gdGhlIGluY3JlYXNlIGluIHJlbW90ZSB3b3JrIGFuZCBvbmxpbmUgam9iIG9wcG9ydHVuaXRpZXMuIEhvd2V2ZXIsIGZvciB0aG9zZSB3aG8gY29udGludWVkIHRvIGNvbW11dGUsIHRoZSB0aW1lIHNwZW50IHRyYXZlbGluZyByZW1haW5lZCBzaWduaWZpY2FudCwgcG9zc2libHkgZHVlIHRvIGhlYXZ5IHRyYWZmaWMgaW4gY2l0aWVzLiANCg0KPGNlbnRlcj4NCmBgYHtyIGRpc3RfdGltZSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQoNCnBsX2NvbSA8LSByZWFkX2R0YSgiQzovUi9maW5hbCBwcm9qZWN0L2RhdGEvcGwuZHRhIiwgY29sX3NlbGVjdCA9IGMoImNpZCIsICJoaWQiLCAicGlkIiwgInN5ZWFyIiwgInBsYjA1OTIiLCAicGxiMDU5MSIsICJwbGIwNTkwIikpDQoNCnBsX2NvbSA8LSBwbF9jb20gJT4lDQogIHJlbmFtZSgNCiAgICBgY29tdGltZWAgPSBwbGIwNTkyLA0KICAgIGBjb21mcmVxYCA9IHBsYjA1OTEsDQogICAgYGNvbWRpc3RgID0gcGxiMDU5MA0KICApDQpwbF9jb20gPC0gcGxfY29tICU+JSANCiAgZmlsdGVyKGNvbXRpbWUgPj0gMCwgY29tZnJlcSA+PSAwLCBjb21kaXN0ID49IDApIA0KDQojIENhbGN1bGF0aW5nIHN0YXRpc3RpY2FsIG1lYXN1cmVzIGJ5IHllYXINCmNvbW11dGluZ19zdGF0c19ieV95ZWFyIDwtIHBsX2NvbSAlPiUNCiAgZ3JvdXBfYnkoc3llYXIpICU+JSAgDQogIHN1bW1hcmlzZSgNCiAgICBNZWFuX0Rpc3RhbmNlID0gbWVhbihjb21kaXN0LCBuYS5ybSA9IFRSVUUpLCAgDQogICAgTWVkaWFuX0Rpc3RhbmNlID0gbWVkaWFuKGNvbWRpc3QsIG5hLnJtID0gVFJVRSksICANCiAgICBSYW5nZV9EaXN0YW5jZSA9IGxpc3QocmFuZ2UoY29tZGlzdCwgbmEucm0gPSBUUlVFKSksICANCiAgICANCiAgICBNZWFuX1RpbWUgPSBtZWFuKGNvbXRpbWUsIG5hLnJtID0gVFJVRSksIA0KICAgIE1lZGlhbl9UaW1lID0gbWVkaWFuKGNvbXRpbWUsIG5hLnJtID0gVFJVRSksICAgDQogICAgUmFuZ2VfVGltZSA9IGxpc3QocmFuZ2UoY29tdGltZSwgbmEucm0gPSBUUlVFKSksICANCiAgICANCiAgICBNb2RlX0ZyZXF1ZW5jeSA9IG5hbWVzKHNvcnQodGFibGUoY29tZnJlcSksIGRlY3JlYXNpbmcgPSBUUlVFKSlbMV0gICMgQ2FsY3VsYXRlIG1vZGUgb2YgY29tbXV0aW5nIGZyZXF1ZW5jeQ0KICApDQoNCg0KZ2dwbG90KGNvbW11dGluZ19zdGF0c19ieV95ZWFyLCBhZXMoeCA9IHN5ZWFyKSkgKw0KICBnZW9tX2NvbChhZXMoeSA9IE1lYW5fRGlzdGFuY2UsIGZpbGwgPSAiTWVhbiBEaXN0YW5jZSAoa20pIiksIGFscGhhID0gMC42LCB3aWR0aCA9IDEsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArDQogIGdlb21fY29sKGFlcyh5ID0gTWVhbl9UaW1lLCBmaWxsID0gIk1lYW4gVGltZSAobWluKSIpLCBhbHBoYSA9IDAuOSwgd2lkdGggPSAxLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC41KSkgKw0KICBsYWJzKHRpdGxlID0gIk1lYW4gRGlzdGFuY2UgYW5kIENvbW11dGluZyBUaW1lIGJ5IFllYXIiLA0KICAgICAgIHggPSAiWWVhciIsDQogICAgICAgeSA9ICJDb21tdXRpbmcgRGlzdGFuY2UgKGttKSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKHNlYy5heGlzID0gc2VjX2F4aXMofi4sIG5hbWUgPSAiQ29tbXV0aW5nIFRpbWUgKG1pbikiKSkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJNZWFuIERpc3RhbmNlIChrbSkiID0gImNvcm5mbG93ZXJibHVlIiwgIk1lYW4gVGltZSAobWluKSIgPSAidG9tYXRvIiksIG5hbWUgPSAiVmFsdWVzIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiY29ybmZsb3dlcmJsdWUiKSwNCiAgICAgICAgYXhpcy50aXRsZS55LnJpZ2h0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gInRvbWF0byIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikNCg0KDQpgYGANCjwvY2VudGVyPg0KDQojIyBDb21tdXRpbmcgRGlzdGFuY2UgdnMuIFRpbWUgYnkgRnJlcXVlbmN5IG9mIENvbW11dGluZyBhbmQgWWVhcg0KDQpUaGlzIHNjYXR0ZXIgcGxvdCBtYXRyaXggdmlzdWFsaXplcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gY29tbXV0aW5nIGRpc3RhbmNlIChpbiBrbSkgYW5kIGNvbW11dGluZyB0aW1lIChpbiBtaW51dGVzKSBmb3IgZGlmZmVyZW50IGNvbW11dGluZyBmcmVxdWVuY2llcyBhbmQgeWVhcnMuDQpUaGUgZGlmZmVyZW50IHBhbmVscyByZXByZXNlbnQgZGlmZmVyZW50IHllYXJzICgyMDE1LCAyMDE3LCAyMDE5KSwgYW5kIHRoZSBwb2ludHMgYXJlIGNvbG9yZWQgYmFzZWQgb24gY29tbXV0aW5nIGZyZXF1ZW5jeS4NCg0KX19NYWluIG9ic2VydmF0aW9uczpfXw0KDQoqIEFzIGV4cGVjdGVkLCB0aGVyZSBpcyBhIGdlbmVyYWwgdHJlbmQgd2hlcmUgbG9uZ2VyIGNvbW11dGluZyBkaXN0YW5jZXMgY29ycmVzcG9uZCB0byBsb25nZXIgY29tbXV0aW5nIHRpbWVzLg0KKiBUaGUgYmxhY2sgZGFzaGVkIGxpbmUgcmVwcmVzZW50cyB0aGUgbWVhbiBjb21tdXRpbmcgdGltZSBmb3IgZWFjaCBkaXN0YW5jZSBjYXRlZ29yeSwgYW5kIGl0IGFwcGVhcnMgdGhhdCBzZXZlcmFsIHBlb3BsZSBjb21tdXRlIGxvbmcgZGlzdGFuY2VzIHJlbGF0aXZlbHkgcXVpY2tseSAobGlrZWx5IGR1ZSB0byBmYXN0ZXIgdHJhbnNwb3J0YXRpb24gbWVhbnMpLg0KKiBIaWdoLWZyZXF1ZW5jeSBjb21tdXRlcnMgKHJlZCBkb3RzKSB0ZW5kIHRvIGhhdmUgbW9yZSBjb25zaXN0ZW50IGNvbW11dGluZyB0aW1lcywgZXZlbiBhdCBsb25nZXIgZGlzdGFuY2VzLCBlc3BlY2lhbGx5IGluIDIwMTksIGNvbXBhcmVkIHRvIGxvd2VyLWZyZXF1ZW5jeSBjb21tdXRlcnMgKGJsdWUgYW5kIGdyZWVuIGRvdHMpLg0KDQo8Y2VudGVyPg0KYGBge3IgZGlzdF90aW1lX2J5X2ZyZXEsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KZ2dwbG90KHBsX2NvbSwgYWVzKHggPSBjb21kaXN0LCB5ID0gY29tdGltZSkpICsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBhcy5mYWN0b3IoY29tZnJlcSkpLCBhbHBoYSA9IDAuNCkgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gImRhc2hlZCIsIGxpbmV3aWR0aCA9IDAuNikgKw0KICBmYWNldF9ncmlkKGNvbWZyZXEgfiBzeWVhcikgKyAgDQogIGxhYnModGl0bGUgPSAiQ29tbXV0aW5nIERpc3RhbmNlIHZzLiBUaW1lIGJ5IEZyZXF1ZW5jeSBvZiBDb21tdXRpbmcgYW5kIFllYXIiLA0KICAgICAgIHggPSAiRGlzdGFuY2UgKGttKSIsDQogICAgICAgeSA9ICJDb21tdXRpbmcgVGltZSAobWluKSIsDQogICAgICAgY29sb3IgPSAiQ29tbXV0aW5nIEZyZXF1ZW5jeSIpICsNCiAgc2NhbGVfY29sb3JfbWFudWFsKA0KICAgIHZhbHVlcyA9IGMoIjEiID0gInRvbWF0byIsICIyIiA9ICJtZWRpdW1zZWFncmVlbiIsICIzIiA9ICJjb3JuZmxvd2VyYmx1ZSIpLCANCiAgICBsYWJlbHMgPSBjKA0KICAgICAgIjEiID0gIlNldmVyYWwgdGltZXMgYSB3ZWVrIiwNCiAgICAgICIyIiA9ICJPbmNlIGEgd2VlayIsDQogICAgICAiMyIgPSAiTGVzcyINCiAgICApDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikNCmBgYA0KPC9jZW50ZXI+DQoNCiMjIEludGVyYWN0aXZlIFNjYXR0ZXIgUGxvdCBvZiBDb21tdXRpbmcgVGltZSB2cy4gTGlmZSBTYXRpc2ZhY3Rpb24gYnkgWWVhcg0KDQpUaGUgc2NhdHRlciBwbG90IGlsbHVzdHJhdGVzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBjb21tdXRpbmcgdGltZSAoaW4gbWludXRlcykgYW5kIGxpZmUgc2F0aXNmYWN0aW9uIGFjcm9zcyB0aHJlZSBkaWZmZXJlbnQgeWVhcnM6IDIwMTUsIDIwMTcsIGFuZCAyMDE5LiBEdXJpbmcgdGhlIGRhdGEgcHJlcGFyYXRpb24gcHJvY2VzcywgdGhlIGluaXRpYWwgZGF0YXNldCBvZiBjaXJjYSA0MDAsMDAwIHJlc3BvbmRlbnRzIHdhcyBzaWduaWZpY2FudGx5IHJlZHVjZWQsIGxlYXZpbmcgb25seSAzNTQgcmVzcG9uZGVudHMgZm9yIGFuYWx5c2lzLiANCg0KX19NYWluIG9ic2VydmF0aW9uczpfXw0KDQoqIEFjcm9zcyBhbGwgdGhyZWUgeWVhcnMsIGxpZmUgc2F0aXNmYWN0aW9uIHNjb3JlcyByYW5nZSBmcm9tIDAgdG8gMTAuIFRoZSBkaXN0cmlidXRpb24gaXMgc29tZXdoYXQgY29uc2lzdGVudCwgd2l0aCBhIG1ham9yaXR5IG9mIHNjb3JlcyBmYWxsaW5nIGJldHdlZW4gNCBhbmQgMTAuIA0KDQoqIE92ZXIgdGhlIHllYXJzLCB0aGVyZSBpcyBhIGNvbnNpc3RlbnQgb2JzZXJ2YXRpb24gdGhhdCBtb2RlcmF0ZSBjb21tdXRpbmcgdGltZXMgKHVuZGVyIDEwMCBtaW51dGVzKSBhcmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBsaWZlIHNhdGlzZmFjdGlvbiBzY29yZXMsIHdoaWNoIGdlbmVyYWxseSByYW5nZSBmcm9tIDYgdG8gOC4NCg0KKiBBIG5vdGljZWFibGUgdHJlbmQgaXMgdGhlIGluY3JlYXNlIGluIGxvd2VyIGxpZmUgc2F0aXNmYWN0aW9uIHNjb3JlcyBhbW9uZyB0aG9zZSB3aXRoIGxvbmdlciBjb21tdXRpbmcgdGltZXMsIGVzcGVjaWFsbHkgaW4gMjAxOS4gDQoNCjxjZW50ZXI+DQpgYGB7ciB0aW1lX2xpZmVzYXQsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KcGxfcGVxdWl2X2NvbXRpbWVfc2F0IDwtIGZ1bGxfam9pbihwbF9jb20sIHBlcXVpdl9jb20sIGJ5ID0gYygicGlkIiwgImhpZCIsICJjaWQiLCAic3llYXIiKSkNCg0KcGxfcGVxdWl2X2NvbXRpbWVfc2F0IDwtIG5hLm9taXQocGxfcGVxdWl2X2NvbXRpbWVfc2F0KQ0KDQoNCnBsX3BlcXVpdl9jb210aW1lX3NhdCA8LSBwbF9wZXF1aXZfY29tdGltZV9zYXQgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubGFiZWxsZWQpLCB+IGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKC4pKSkpDQoNCiMgU3BsaXRpbmcgdGhlIGRhdGEgYnkgJ3N5ZWFyJw0KcGxfcGVxdWl2X2NvbXRpbWVfc2F0X3NwbGl0IDwtIHNwbGl0KHBsX3BlcXVpdl9jb210aW1lX3NhdCwgcGxfcGVxdWl2X2NvbXRpbWVfc2F0JHN5ZWFyKQ0KDQpsaWJyYXJ5KHBsb3RseSkNCg0KIyBEZWZpbmluZyBjb2xvcnMgZm9yIGVhY2ggeWVhcg0KY29sb3JzIDwtIGMoJzIwMTUnID0gJ2Nvcm5mbG93ZXJibHVlJywgJzIwMTcnID0gJ21lZGl1bXNlYWdyZWVuJywgJzIwMTknID0gJ3RvbWF0bycpDQoNCiMgQ3JlYXRpbmcgaW5kaXZpZHVhbCBwbG90cyBmb3IgZWFjaCB5ZWFyDQpwbG90cyA8LSBsYXBwbHkobmFtZXMocGxfcGVxdWl2X2NvbXRpbWVfc2F0X3NwbGl0KSwgZnVuY3Rpb24oeWVhcikgew0KICBwbG90X2x5KA0KICAgIGRhdGEgPSBwbF9wZXF1aXZfY29tdGltZV9zYXRfc3BsaXRbW3llYXJdXSwgDQogICAgeCA9IH5jb210aW1lLCANCiAgICB5ID0gfmxpZmVzYXQsIA0KICAgIHR5cGUgPSAnc2NhdHRlcicsIA0KICAgIG1vZGUgPSAnbWFya2VycycsDQogICAgbWFya2VyID0gbGlzdChzaXplID0gMTAsIGNvbG9yID0gY29sb3JzW3llYXJdLA0KICAgICAgICAgICAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnYmxhY2snLCB3aWR0aCA9IDAuNSkpLA0KICAgIG5hbWUgPSBwYXN0ZSgiWWVhcjoiLCB5ZWFyKSANCiAgKSAlPiUNCiAgICBsYXlvdXQoDQogICAgICB0aXRsZSA9IHBhc3RlKCJZZWFyOiIsIHllYXIpLA0KICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkNvbW11dGluZyBUaW1lIChtaW4pIiwgDQogICAgICAgICAgICAgICAgICAgdGl0bGVmb250ID0gbGlzdChzaXplID0gMTApKSwNCiAgICAgIHlheGlzID0gbGlzdCh0aXRsZSA9ICJMaWZlIFNhdGlzZmFjdGlvbiIpDQogICAgKQ0KfSkNCg0KIyBDb21iaW5laW5nIHBsb3RzIGludG8gYSBzdWJwbG90DQpzdWJwbG90KA0KICBwbG90c1tbMV1dLCAjIDIwMTUNCiAgcGxvdHNbWzJdXSwgIyAyMDE3DQogIHBsb3RzW1szXV0sICMgMjAxOQ0KICBucm93cyA9IDEsICMgQXJyYW5nZSBpbiBhIHNpbmdsZSByb3cNCiAgc2hhcmVYID0gVFJVRSwgDQogIHNoYXJlWSA9IFRSVUUsIA0KICB0aXRsZVggPSBUUlVFLCANCiAgdGl0bGVZID0gVFJVRSwgDQogIG1hcmdpbiA9IDAuMDUgDQopICU+JQ0KICBsYXlvdXQoDQogICAgdGl0bGUgPSAiSW50ZXJhY3RpdmUgU2NhdHRlciBQbG90IG9mIENvbW11dGluZyBUaW1lIHZzLiBMaWZlIFNhdGlzZmFjdGlvbiBieSBZZWFyIiwNCiAgICBzaG93bGVnZW5kID0gVFJVRSwNCiAgICBsZWdlbmQgPSBsaXN0KA0KICAgICAgZm9udCA9IGxpc3Qoc2l6ZSA9IDEwKQ0KICApKQ0KDQpgYGANCjwvY2VudGVyPg0KDQpUaGlzIGNvcnJlbGF0aW9uIHByb3ZlcyB0aGUgcGxvdMK0cyByZXN1bHRzIGFuZCBzaG93cyB0aGUgYWJzZW5jZSBvZiBhbG1vc3QgYW55ICpkaXJlY3QqIGNvbm5lY3Rpb24gYmV0d2VlbiBjb21tdXRpbmcgdGltZSBhbmQgbGlmZSBzYXRpc2ZhY3Rpb24uDQoNCjxjZW50ZXI+DQpgYGB7ciBjb3JfdGltZV9saWZlc2F0LCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCmNvcl90aW1lX2xpZmVzYXQgPC0gY29yKHBsX3BlcXVpdl9jb210aW1lX3NhdCRjb210aW1lLCBwbF9wZXF1aXZfY29tdGltZV9zYXQkbGlmZXNhdCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQpwcmludChwYXN0ZSgiQ29ycmVsYXRpb24gY29lZmZpY2llbnQgb2YgbGlmZSBzYXRpc2ZhY3Rpb24gYW5kIGNvbW11dGluZyB0aW1lOiIsIGNvcl90aW1lX2xpZmVzYXQpKQ0KYGBgDQo8L2NlbnRlcj4NCg0KDQpUaGUgYW5hbHlzaXMgb2YgY29tbXV0aW5nIHBhdHRlcm5zIG92ZXIgdGhlIHllYXJzIHJldmVhbHMgc2V2ZXJhbCBpbXBvcnRhbnQgdHJlbmRzLiANCg0KICAgICogRmlyc3QsIHRoZSBkZWNyZWFzZSBpbiBjb21tdXRpbmcgZGlzdGFuY2VzIHBvc3QtMjAxNyBsaWtlbHkgcmVmbGVjdHMgdGhlIGdyb3dpbmcgYWRvcHRpb24gb2YgcmVtb3RlIHdvcmssIHlldCBjb21tdXRpbmcgdGltZSBoYXMgcmVtYWluZWQgbGFyZ2VseSB1bmNoYW5nZWQsIGhpZ2hsaWdodGluZyBwZXJzaXN0ZW50IGluZWZmaWNpZW5jaWVzIGluIHRyYW5zcG9ydGF0aW9uLiANCiAgICANCiAgICAqIFNlY29uZCwgZnJlcXVlbnQgY29tbXV0ZXJzIHRlbmQgdG8gaGF2ZSBtb3JlIHByZWRpY3RhYmxlIGFuZCBjb25zaXN0ZW50IGNvbW11dGluZyB0aW1lcywgc3VnZ2VzdGluZyB0aGF0IGV4cGVyaWVuY2Ugb3IgYWNjZXNzIHRvIGJldHRlciB0cmFuc3BvcnQgb3B0aW9ucyBwbGF5cyBhIHJvbGUgaW4gbWFuYWdpbmcgY29tbXV0ZXMgZWZmZWN0aXZlbHkuIA0KICAgIA0KICAgICogRmluYWxseSwgd2hpbGUgbG9uZ2VyIGNvbW11dGVzIGNhbiBuZWdhdGl2ZWx5IGltcGFjdCBsaWZlIHNhdGlzZmFjdGlvbiwgdGhlIHJlbGF0aW9uc2hpcCBpcyBjb21wbGV4IGFuZCBsaWtlbHkgaW5mbHVlbmNlZCBieSB2YXJpb3VzIGV4dGVybmFsIGZhY3RvcnMuDQoNClRoZXNlIGluc2lnaHRzIGVtcGhhc2l6ZSB0aGUgaW1wb3J0YW5jZSBvZiB1bmRlcnN0YW5kaW5nIHRoZSBicm9hZGVyIGNvbnRleHQgb2YgY29tbXV0aW5nIGJlaGF2aW9ycyBhbmQgdGhlaXIgaW1wYWN0IG9uIHdlbGwtYmVpbmcuIA0KDQoNCiMgSW5jb21lIGFuZCBsaWZlIHNhdGlzZmFjdGlvbiB7LnRhYnNldH0NCg0KSW4gYSBwcmV2aW91cyBzZWN0aW9uLCBJIGV4YW1pbmVkIGhvdXNlaG9sZCBpbmNvbWUgYW5kIGluZGl2aWR1YWwgaW5jb21lIHBlciBmYW1pbHkgbWVtYmVyLCBvYnNlcnZpbmcgYSBzdGVhZHkgaW5jcmVhc2UgaW4gYm90aCBvdmVyIG5lYXJseSA0MCB5ZWFycy4gQnVpbGRpbmcgb24gdGhlc2UgZmluZGluZ3MsIHRoaXMgcGFydCBkZWx2ZXMgZGVlcGVyIGludG8gdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluZGl2aWR1YWwgaW5jb21lIGFuZCBsaWZlIHNhdGlzZmFjdGlvbi4gVW5kZXJzdGFuZGluZyBob3cgcGVyc29uYWwgZmluYW5jaWFsIHN0YWJpbGl0eSBpbmZsdWVuY2VzIHdlbGwtYmVpbmcgY2FuIHByb3ZpZGUgdmFsdWFibGUgaW5zaWdodHMgaW50byB0aGUgYnJvYWRlciBzb2Npb2Vjb25vbWljIGZhY3RvcnMgdGhhdCBjb250cmlidXRlIHRvIGhhcHBpbmVzcyBhbmQgb3ZlcmFsbCBxdWFsaXR5IG9mIGxpZmUuIA0KVGhpcyBhbmFseXNpcyBhaW1zIHRvIGV4cGxvcmUgd2hldGhlciByaXNpbmcgaW5jb21lcyBhcmUgY29uc2lzdGVudGx5IGxpbmtlZCB0byBoaWdoZXIgbGV2ZWxzIG9mIGxpZmUgc2F0aXNmYWN0aW9uLg0KDQojIyBDb3JyZWxhdGlvbiBiZXR3ZWVuIGhvdXNlaG9sZCBpbmNvbWUgYW5kIGxpZmUgc2F0aXNmYWN0aW9uDQpUaGlzIGNvcnJlbGF0aW9uIHN1Z2dlc3RzIHRoYXQgaW5jcmVhc2luZyBob3VzZWhvbGQgaW5jb21lIGNhbiBjb250cmlidXRlIHRvIGltcHJvdmVkIGxpZmUgc2F0aXNmYWN0aW9uLCBidXQgaXQgaXMgbm90IHRoZSBzb2xlIGZhY3Rvci4gDQoNCjxjZW50ZXI+DQpgYGB7ciBjb3JfaGhpbmNvbWVfc2F0X2xpZmVzYXQsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KDQpwZXF1aXZfbGlmZXNhdCA8LSByZWFkX2R0YSgiQzovUi9maW5hbCBwcm9qZWN0L2RhdGEvcGVxdWl2LmR0YSIsIGNvbF9zZWxlY3QgPSBjKCJjaWQiLCAiaGlkIiwgInBpZCIsICJzeWVhciIsICJwMTExMDEiKSkNCg0KcGVxdWl2X2xpZmVzYXQgPC0gcGVxdWl2X2xpZmVzYXQgJT4lIA0KICByZW5hbWUoDQogICAgbGlmZV9zYXQgPSBwMTExMDENCiAgKQ0KICANCiMgTWVyZ2luZyB0aGUgdHdvIGRhdGFzZXRzIGJ5IHBpZCBhbmQgc3llYXINCnBsX3BlcXVpdl9zYXQgPC0gZnVsbF9qb2luKHBsX2hoaW5jX2RhdGEsIHBlcXVpdl9saWZlc2F0LCBieSA9IGMoInBpZCIsICJoaWQiLCAiY2lkIiwgInN5ZWFyIikpDQoNCnBsX3BlcXVpdl9zYXQgPC0gbmEub21pdChwbF9wZXF1aXZfc2F0KQ0KDQpwbF9wZXF1aXZfc2F0IDwtIHBsX3BlcXVpdl9zYXQgJT4lDQogIGZpbHRlcl9hbGwoYWxsX3ZhcnMoLiA+PSAwKSkNCg0KDQpjb3JyZWxhdGlvbl9pbmNzYXRfbGlmZXNhdCA8LSByb3VuZChjb3IocGxfcGVxdWl2X3NhdCRsaWZlX3NhdCwgcGxfcGVxdWl2X3NhdCRoaGluY19zYXQsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKSwgMykNCg0KcHJpbnQocGFzdGUoIkNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGJldHdlZW4gc2F0aXNmYWN0aW9uIHdpdGggaGF1c2Vob2xkIGluY29tZSBhbmQgb3ZlcmFsbCBsaWZlIHNhdGlzZmFjdGlvbjoiLCBjb3JyZWxhdGlvbl9pbmNzYXRfbGlmZXNhdCkpDQpgYGANCg0KIyMgQ29ycmVsYXRpb24gYmV0d2VlbiBPdmVyYWxsIExpZmUgU2F0aXNmYWN0aW9uIGFuZCBTYXRpc2ZhY3Rpb24gV2l0aCBQZXJzb25hbCBJbmNvbWUgYnkgWWVhcg0KDQpUaGUgcHJvdmlkZWQgZ3JhcGggaWxsdXN0cmF0ZXMgdGhlIGNvcnJlbGF0aW9uIGJldHdlZW4gb3ZlcmFsbCBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgc2F0aXNmYWN0aW9uIHdpdGggcGVyc29uYWwgaW5jb21lIGZyb20gMTk4NCB0byAyMDIwLiANCg0KUG9zdC0xOTkwLCB0aGVyZSBpcyBhIGRlY2xpbmUgaW4gdGhlIGNvcnJlbGF0aW9uLCBmb2xsb3dlZCBieSBzZXZlcmFsIGZsdWN0dWF0aW9ucy4gVGhlIGRlY2xpbmUgaW4gdGhlIGNvcnJlbGF0aW9uIGZyb20gdGhlIG1pZC0yMDAwcyBvbndhcmQgc3VnZ2VzdHMgdGhhdCB0aGUgYXNzb2NpYXRpb24gYmV0d2VlbiBsaWZlIHNhdGlzZmFjdGlvbiBhbmQgaW5jb21lIHNhdGlzZmFjdGlvbiBiZWNhbWUgd2Vha2VyIG92ZXIgdGltZS4gVGhpcyBjb3VsZCBpbXBseSB0aGF0IGZhY3RvcnMgb3RoZXIgdGhhbiBpbmNvbWUgc2F0aXNmYWN0aW9uIG1heSBoYXZlIHN0YXJ0ZWQgdG8gcGxheSBhIG1vcmUgc2lnbmlmaWNhbnQgcm9sZSBpbiBkZXRlcm1pbmluZyBvdmVyYWxsIGxpZmUgc2F0aXNmYWN0aW9uLg0KDQpgYGB7ciBwaW5jc2F0X2xpZmVzYXQsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQ0KcGxfcGVxdWl2X3NhdF9jb3IgPC0gcGxfcGVxdWl2X3NhdCAlPiUNCiAgZ3JvdXBfYnkoc3llYXIpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgQ29ycmVsYXRpb24gPSBjb3IobGlmZV9zYXQsIGhoaW5jX3NhdCwgdXNlID0gImNvbXBsZXRlLm9icyIpDQogICkNCg0KZ2dwbG90KHBsX3BlcXVpdl9zYXRfY29yLCBhZXMoeCA9IHN5ZWFyLCB5ID0gQ29ycmVsYXRpb24pKSArDQogIGdlb21fbGluZShjb2xvciA9ICJjb3JuZmxvd2VyYmx1ZSIsIGxpbmV3aWR0aCA9IDAuMikgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImNvcm5mbG93ZXJibHVlIiwgc2l6ZSA9IDIpICsNCiAgbGFicyh0aXRsZSA9ICJDb3JyZWxhdGlvbiBiZXR3ZWVuIE92ZXJhbGwgTGlmZSBTYXRpc2ZhY3Rpb24gYW5kIFNhdGlzZmFjdGlvbiBXaXRoIFBlcnNvbmFsIEluY29tZSBieSBZZWFyIiwNCiAgICAgICB4ID0gIlllYXIiLA0KICAgICAgIHkgPSAiQ29ycmVsYXRpb24gQ29lZmZpY2llbnQiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUsIHNpemUgPSAxMCkgKSArDQogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKHBsX3BlcXVpdl9zYXRfY29yJHN5ZWFyKSwgbWF4KHBsX3BlcXVpdl9zYXRfY29yJHN5ZWFyKSwgYnkgPSAyKSkgDQoNCg0KYGBgDQo8L2NlbnRlcj4NCg0KVGhlICJDb21wYXJpc29uIG9mIE1lYW4gUGVyIENhcGl0YSBJbmNvbWUgYW5kIExpZmUgU2F0aXNmYWN0aW9uIGJ5IFllYXIiIGdyYXBoIGNvbXBhcmVzIHRoZSB0cmVuZHMgaW4gbWVhbiBwZXIgY2FwaXRhIGluY29tZSBhbmQgbWVhbiBsaWZlIHNhdGlzZmFjdGlvbiBvdmVyIHRpbWUsIGlsbHVzdHJhdGluZyB0aGVpciBzZXBhcmF0ZSB0cmFqZWN0b3JpZXMgYW5kIHJlbGF0aXZlIHNjYWxlcy4NCg0KVGhlIHBhcmFsbGVsIGluY3JlYXNlIGluIGJvdGggaW5jb21lIGFuZCBsaWZlIHNhdGlzZmFjdGlvbiBzdWdnZXN0cyBhIHBvc2l0aXZlIGNvcnJlbGF0aW9uIGJldHdlZW4gZmluYW5jaWFsIHdlbGwtYmVpbmcgYW5kIG92ZXJhbGwgaGFwcGluZXNzLiBIb3dldmVyLCB0aGUgbGVzcyBwcm9ub3VuY2VkIHJpc2UgaW4gbGlmZSBzYXRpc2ZhY3Rpb24gY29tcGFyZWQgdG8gaW5jb21lIGdyb3d0aCBpbmRpY2F0ZXMgZGltaW5pc2hpbmcgcmV0dXJucy4gX19fQWZ0ZXIgYSBjZXJ0YWluIHBvaW50LCBhZGRpdGlvbmFsIGluY29tZSBtYXkgaGF2ZSBhIHJlZHVjZWQgaW1wYWN0IG9uIGxpZmUgc2F0aXNmYWN0aW9uLl9fXw0KPGNlbnRlcj4NCmBgYHtyIHBpbmNfbGlmZXNhdCwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9DQpwZXF1aXZfaGhzaXplX2RhdGEgPC0gcmVhZF9kdGEoIkM6L1IvZmluYWwgcHJvamVjdC9kYXRhL3BlcXVpdi5kdGEiLCBjb2xfc2VsZWN0ID0gYygiY2lkIiwgImhpZCIsICJwaWQiLCAic3llYXIiLCAiZDExMTA2IiwgImQxMTEwNyIsInAxMTEwMSIpKQ0KDQpwZXF1aXZfaGhzaXplX2RhdGEgPC0gcGVxdWl2X2hoc2l6ZV9kYXRhICU+JQ0KICByZW5hbWUoDQogICAgYGhoX3NpemVgID0gZDExMTA2LA0KICAgIGBoaF9jaGlsZGAgPSBkMTExMDcsDQogICAgYGxpZmVfc2F0YCA9IHAxMTEwMQ0KICApDQoNCmhnZW5fcGVxdWl2X21lcmdlZCA8LSBmdWxsX2pvaW4oaGdlbl9oaGluY19kYXRhLCBwZXF1aXZfaGhzaXplX2RhdGEsIGJ5ID0gYygiY2lkIiwgImhpZCIsICJzeWVhciIpKQ0KDQpoZ2VuX3BlcXVpdl9tZXJnZWQgPC0gbmEub21pdChoZ2VuX3BlcXVpdl9tZXJnZWQpDQpoZ2VuX3BlcXVpdl9tZXJnZWQgPC0gaGdlbl9wZXF1aXZfbWVyZ2VkICU+JSBmaWx0ZXIobW9udGhseV9oaGluYyA+PSAwLCBoaF9zaXplID4gMCwgaGhfY2hpbGQgPj0gMCwgbGlmZV9zYXQgPj0gMCkgJT4lIA0KICBmaWx0ZXIoaGhfc2l6ZSA+IGhoX2NoaWxkKQ0KDQojIENhbGN1bGF0aW5nIFBlciBDYXBpdGEgSG91c2Vob2xkIEluY29tZQ0KaGdlbl9wZXF1aXZfbWVyZ2VkIDwtIGhnZW5fcGVxdWl2X21lcmdlZCAlPiUNCiAgbXV0YXRlKA0KICAgIHBlcl9jYXBpdGFfaW5jb21lID0gbW9udGhseV9oaGluYyAvIChoaF9zaXplIC0gaGhfY2hpbGQpDQogICkNCg0KIyBDYWxjdWxhdGluZyB0aGUgbWVhbiBwZXIgY2FwaXRhIGluY29tZSBhbmQgbGlmZSBzYXRpc2ZhY3Rpb24gYnkgeWVhcg0KaGdlbl9wZXF1aXZfbWVhbiA8LSBoZ2VuX3BlcXVpdl9tZXJnZWQgJT4lDQogIGdyb3VwX2J5KHN5ZWFyKSAlPiUNCiAgc3VtbWFyaXplKA0KICAgIG1lYW5fcGVyX2NhcGl0YV9pbmNvbWUgPSByb3VuZChtZWFuKHBlcl9jYXBpdGFfaW5jb21lLCBuYS5ybSA9IFRSVUUpLCAxKSwNCiAgICBtZWFuX2xpZmVfc2F0ID0gcm91bmQobWVhbihsaWZlX3NhdCwgbmEucm0gPSBUUlVFKSwgMSkNCiAgKQ0KDQojIG1lYW4gcGVyIGNhcGl0YSBpbmNvbWUgYW5kIG1lYW4gbGlmZSBzYXRpc2ZhY3Rpb24gYnkgeWVhcg0Kc2NhbGVfZmFjdG9yIDwtIG1heChoZ2VuX3BlcXVpdl9tZWFuJG1lYW5fcGVyX2NhcGl0YV9pbmNvbWUsIG5hLnJtID0gVFJVRSkgLyBtYXgoaGdlbl9wZXF1aXZfbWVhbiRtZWFuX2xpZmVfc2F0LCBuYS5ybSA9IFRSVUUpDQoNCiMgbWVhbiBwZXIgY2FwaXRhIGluY29tZSBhbmQgbWVhbiBsaWZlIHNhdGlzZmFjdGlvbiBieSB5ZWFyDQogc2NhbGVfZmFjdG9yIDwtIG1heChoZ2VuX3BlcXVpdl9tZWFuJG1lYW5fcGVyX2NhcGl0YV9pbmNvbWUpIC8gbWF4KGhnZW5fcGVxdWl2X21lYW4kbWVhbl9saWZlX3NhdCkNCiANCiAgZ2dwbG90KGhnZW5fcGVxdWl2X21lYW4sIGFlcyh4ID0gc3llYXIpKSArDQogICBnZW9tX2xpbmUoYWVzKHkgPSBtZWFuX3Blcl9jYXBpdGFfaW5jb21lLCBjb2xvciA9ICJNZWFuIFBlciBDYXBpdGEgSW5jb21lIiksIGxpbmV3aWR0aCA9IDAuMikgKw0KICAgZ2VvbV9wb2ludChhZXMoeSA9IG1lYW5fcGVyX2NhcGl0YV9pbmNvbWUsIGNvbG9yID0gIk1lYW4gUGVyIENhcGl0YSBJbmNvbWUiKSwgc2l6ZSA9IDEuNikgKw0KICAgZ2VvbV9saW5lKGFlcyh5ID0gbWVhbl9saWZlX3NhdCAqIHNjYWxlX2ZhY3RvciwgY29sb3IgPSAiTWVhbiBMaWZlIFNhdGlzZmFjdGlvbiIpLCBsaW5ld2lkdGggPSAwLjIpICsNCiAgIGdlb21fcG9pbnQoYWVzKHkgPSBtZWFuX2xpZmVfc2F0ICogc2NhbGVfZmFjdG9yLCBjb2xvciA9ICJNZWFuIExpZmUgU2F0aXNmYWN0aW9uIiksIHNpemUgPSAxLjYpICsNCiAgIHNjYWxlX3lfY29udGludW91cygNCiAgICAgbmFtZSA9ICJNZWFuIFBlciBDYXBpdGEgSW5jb21lIiwNCiAgICAgc2VjLmF4aXMgPSBzZWNfYXhpcyh+IC4gLyBzY2FsZV9mYWN0b3IsIG5hbWUgPSAiTWVhbiBMaWZlIFNhdGlzZmFjdGlvbiIpDQogICApICsNCiAgIGxhYnMoDQogICAgIHRpdGxlID0gIkNvbXBhcmlzb24gb2YgTWVhbiBQZXIgQ2FwaXRhIEluY29tZSBhbmQgTGlmZSBTYXRpc2ZhY3Rpb24gYnkgWWVhciIsDQogICAgIHggPSAiWWVhciIsDQogICAgIGNvbG9yID0gIk1ldHJpY3MiDQogICApICsNCiAgIHRoZW1lX21pbmltYWwoKSArDQogICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiTWVhbiBQZXIgQ2FwaXRhIEluY29tZSIgPSAiY29ybmZsb3dlcmJsdWUiLCAiTWVhbiBMaWZlIFNhdGlzZmFjdGlvbiIgPSAidG9tYXRvIikpDQpgYGANCjwvY2VudGVyPg0KDQpBIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG9mIDAuNDY1IGluZGljYXRlcyBhIG1vZGVyYXRlIHBvc2l0aXZlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSB0d28gdmFyaWFibGVzIGluIHF1ZXN0aW9uLiBJdCBzdWdnZXN0cyB0aGF0IHRoZXJlIGlzIGEgbW9kZXJhdGUgdGVuZGVuY3kgZm9yIGhpZ2hlciBzYXRpc2ZhY3Rpb24gd2l0aCBwZXJzb25hbCBpbmNvbWUgdG8gYmUgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBvdmVyYWxsIGxpZmUgc2F0aXNmYWN0aW9uLCBidXQgaXQgYWxzbyBpbmRpY2F0ZXMgdGhhdCBvdGhlciBmYWN0b3JzIG1heSBiZSBjb250cmlidXRpbmcgdG8gb3ZlcmFsbCBsaWZlIHNhdGlzZmFjdGlvbi4NCjxjZW50ZXI+DQpgYGB7ciBjb3JfcGluY19saWZlc2F0LCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0NCiAgY29yX3BpbmNfbGlmZXNhdCA8LSByb3VuZChjb3IoaGdlbl9wZXF1aXZfbWVhbiRtZWFuX3Blcl9jYXBpdGFfaW5jb21lLCBoZ2VuX3BlcXVpdl9tZWFuJG1lYW5fbGlmZV9zYXQsIHVzZSA9ICJjb21wbGV0ZS5vYnMiKSwgMykNCiAgcHJpbnQocGFzdGUoIkNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IG9mIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBjb21tdXRpbmcgdGltZToiLCBjb3JfcGluY19saWZlc2F0KSkNCmBgYA0KPC9jZW50ZXI+DQoNClRoZSBhbmFseXNpcyBvZiBpbmNvbWUgYW5kIGxpZmUgc2F0aXNmYWN0aW9uIGRhdGEgb3ZlciBzZXZlcmFsIGRlY2FkZXMgcmV2ZWFscyBhIG51YW5jZWQgcmVsYXRpb25zaGlwIGJldHdlZW4gZmluYW5jaWFsIHdlbGwtYmVpbmcgYW5kIGhhcHBpbmVzcy4gV2hpbGUgaW5jb21lIGdyb3d0aCBpcyBwb3NpdGl2ZWx5IGNvcnJlbGF0ZWQgd2l0aCBpbmNyZWFzZWQgbGlmZSBzYXRpc2ZhY3Rpb24sIHRoZSByZWxhdGlvbnNoaXAgaXMgbm90IGFic29sdXRlLiBUaGUgY29ycmVsYXRpb24gYmV0d2VlbiBpbmNvbWUgc2F0aXNmYWN0aW9uIGFuZCBvdmVyYWxsIGxpZmUgc2F0aXNmYWN0aW9uIGhhcyBkZWNsaW5lZCBvdmVyIHRpbWUsIHN1Z2dlc3RpbmcgdGhlIGdyb3dpbmcgaW1wb3J0YW5jZSBvZiBub24tZmluYW5jaWFsIGZhY3RvcnMgaW4gc2hhcGluZyB3ZWxsLWJlaW5nLiBUaGVzZSBmaW5kaW5ncyBoaWdobGlnaHQgdGhlIGNvbXBsZXhpdHkgb2YgaGFwcGluZXNzLCB3aGVyZSBmaW5hbmNpYWwgc2VjdXJpdHkgaXMgbmVjZXNzYXJ5IGJ1dCBub3Qgc3VmZmljaWVudC4NCg0KIyBDb25jbHVzaW9uDQoNClRoZSBhbmFseXNpcyBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaGFwcGluZXNzIChtZWFzdXJlZCBhcyBsaWZlIHNhdGlzZmFjdGlvbikgYW5kIGNvbW11dGluZywgYXMgd2VsbCBhcyBvdGhlciBzb2Npby1lY29ub21pYyBmYWN0b3JzLCByZXZlYWxzIGEgY29tcGxleCBpbnRlcnBsYXkgb2YgdmFyaWFibGVzIHRoYXQgaW5mbHVlbmNlIGluZGl2aWR1YWwgd2VsbC1iZWluZy4gDQoNCl9fTWFpbiBmaW5kaW5nczpfXw0KDQoqIF9fQ29tbXV0aW5nIGFuZCBIYXBwaW5lc3NfXzogQ29uc2lzdGVudCB3aXRoIHRoZSBsaXRlcmF0dXJlLCBsb25nZXIgY29tbXV0aW5nIHRpbWVzIGFyZSBnZW5lcmFsbHkgYXNzb2NpYXRlZCB3aXRoIGxvd2VyIGxldmVscyBvZiBsaWZlIHNhdGlzZmFjdGlvbi4gVGhlIGFuYWx5c2lzIHJldmVhbHMgdGhhdCBpbmRpdmlkdWFscyB3aXRoIGxvbmdlciBjb21tdXRpbmcgZGlzdGFuY2VzIHRlbmQgdG8gcmVwb3J0IGxvd2VyIGhhcHBpbmVzcyBsZXZlbHMuIFRoaXMgc3VwcG9ydHMgdGhlICJjb21tdXRpbmcgcGFyYWRveCIgaWRlbnRpZmllZCBpbiBwcmV2aW91cyBzdHVkaWVzLCB3aGVyZSB0aGUgbmVnYXRpdmUgaW1wYWN0IG9mIGxvbmdlciBjb21tdXRlcyBvbiB3ZWxsLWJlaW5nIG9mdGVuIG91dHdlaWdocyB0aGUgcG90ZW50aWFsIGJlbmVmaXRzIG9mIGJldHRlciBlbXBsb3ltZW50IG9wcG9ydHVuaXRpZXMgb3IgaGlnaGVyIGluY29tZSBhc3NvY2lhdGVkIHdpdGggbG9uZ2VyIGRpc3RhbmNlcy4NCg0KKiBfX0luY29tZSBhbmQgSGFwcGluZXNzX186IFRoZSBhbmFseXNpcyBvZiBpbmNvbWUgZGF0YSBoaWdobGlnaHRzIGEgbW9kZXJhdGUgcG9zaXRpdmUgY29ycmVsYXRpb24gYmV0d2VlbiBob3VzZWhvbGQgaW5jb21lIGFuZCBsaWZlIHNhdGlzZmFjdGlvbiwgc3VnZ2VzdGluZyB0aGF0IGZpbmFuY2lhbCBzdGFiaWxpdHkgY29udHJpYnV0ZXMgdG8gaGFwcGluZXNzLiBIb3dldmVyLCB0aGUgZGltaW5pc2hpbmcgcmV0dXJucyBvYnNlcnZlZCBpbmRpY2F0ZSB0aGF0IGJleW9uZCBhIGNlcnRhaW4gcG9pbnQsIGFkZGl0aW9uYWwgaW5jb21lIGhhcyBhIHJlZHVjZWQgaW1wYWN0IG9uIGxpZmUgc2F0aXNmYWN0aW9uLiBUaGlzIGZpbmRpbmcgYWxpZ25zIHdpdGggdGhlIG5vdGlvbiB0aGF0IHdoaWxlIGluY29tZSBpcyBjcnVjaWFsIGZvciB3ZWxsLWJlaW5nLCBpdCBpcyBub3QgdGhlIHNvbGUgZGV0ZXJtaW5hbnQgb2YgaGFwcGluZXNzLiBJbnRlcmVzdGluZ2x5LCB3aGVuIGNvbW11dGluZyBpcyBmYWN0b3JlZCBpbiwgaW5kaXZpZHVhbHMgd2l0aCBoaWdoZXIgaW5jb21lcyBhbmQgbG9uZ2VyIGNvbW11dGVzIGRvIG5vdCBuZWNlc3NhcmlseSByZXBvcnQgaGlnaGVyIGhhcHBpbmVzcyBsZXZlbHMsIGVtcGhhc2l6aW5nIHRoZSBjb21wbGV4IHRyYWRlLW9mZnMgYmV0d2VlbiBmaW5hbmNpYWwgYmVuZWZpdHMgYW5kIHRoZSB0aW1lIGNvc3RzIG9mIGNvbW11dGluZy4NCg0KKiBfX0VkdWNhdGlvbiBhbmQgRW1wbG95bWVudF9fOiBIaWdoZXIgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCBpcyBnZW5lcmFsbHkgYXNzb2NpYXRlZCB3aXRoIGhpZ2hlciBsaWZlIHNhdGlzZmFjdGlvbiwgYXMgaXQgb2Z0ZW4gbGVhZHMgdG8gYmV0dGVyIGVtcGxveW1lbnQgb3Bwb3J0dW5pdGllcyBhbmQgZmluYW5jaWFsIHN0YWJpbGl0eS4gVGhpcyBhbmFseXNpcyBzaG93cyB0aGF0IGluZGl2aWR1YWxzIHdpdGggbW9yZSB5ZWFycyBvZiBlZHVjYXRpb24gYXJlIG1vcmUgbGlrZWx5IHRvIGJlIGVtcGxveWVkIGZ1bGwtdGltZSBhbmQgcmVwb3J0IGhpZ2hlciBoYXBwaW5lc3MgbGV2ZWxzLiBIb3dldmVyLCB0aG9zZSBpbiBsb3dlci1wYXlpbmcgam9icyBvciB3aXRoIGlycmVndWxhciBlbXBsb3ltZW50IHBhdHRlcm5zIHJlcG9ydCBsb3dlciBsaWZlIHNhdGlzZmFjdGlvbiwgZXZlbiBpZiB0aGVpciBjb21tdXRpbmcgdGltZXMgYXJlIHNob3J0ZXIuIFRoaXMgc3VnZ2VzdHMgdGhhdCBlbXBsb3ltZW50IHF1YWxpdHksIG5vdCBqdXN0IHRoZSBwcmVzZW5jZSBvZiBhIGpvYiwgaXMgYSBjcml0aWNhbCBmYWN0b3IgaW4gdGhlIGNvbW11dGluZy1oYXBwaW5lc3MgZXF1YXRpb24uDQoNCiogX19Db21tdXRpbmcgUGF0dGVybnNfXzogVGhlIGFuYWx5c2lzIG9mIGNvbW11dGluZyBwYXR0ZXJucyBvdmVyIHRpbWUgcmV2ZWFscyBhIHRyZW5kIHRvd2FyZHMgc2hvcnRlciBjb21tdXRpbmcgZGlzdGFuY2VzIGFuZCB0aW1lcywgbGlrZWx5IGluZmx1ZW5jZWQgYnkgdGhlIHJpc2Ugb2YgcmVtb3RlIHdvcmsgYW5kIGZsZXhpYmxlIHdvcmtpbmcgYXJyYW5nZW1lbnRzLiBXaGlsZSB0aGlzIHNoaWZ0IGhhcyB0aGUgcG90ZW50aWFsIHRvIGVuaGFuY2UgbGlmZSBzYXRpc2ZhY3Rpb24gYnkgcmVkdWNpbmcgZGFpbHkgc3RyZXNzIGFuZCB0aW1lIGxvc3QgdG8gY29tbXV0aW5nLCB0aGUgb3ZlcmFsbCBpbXBhY3Qgb24gaGFwcGluZXNzIGFsc28gZGVwZW5kcyBvbiBvdGhlciBzb2Npby1lY29ub21pYyBmYWN0b3JzLCBzdWNoIGFzIGluY29tZSwgZW1wbG95bWVudCBzdGF0dXMsIGFuZCBob3VzZWhvbGQgY29tcG9zaXRpb24uDQoNCiogX19JbmNvbWUgU2F0aXNmYWN0aW9uIGFuZCBMaWZlIFNhdGlzZmFjdGlvbl9fOiBUaGUgY29ycmVsYXRpb24gYmV0d2VlbiBvdmVyYWxsIGxpZmUgc2F0aXNmYWN0aW9uIGFuZCBzYXRpc2ZhY3Rpb24gd2l0aCBwZXJzb25hbCBpbmNvbWUgaGFzIHdlYWtlbmVkIG92ZXIgdGltZSwgc3VnZ2VzdGluZyB0aGF0IG90aGVyIGZhY3RvcnMgYmV5b25kIGluY29tZSwgc3VjaCBhcyB3b3JrLWxpZmUgYmFsYW5jZSwgY29tbXV0aW5nIHRpbWUsIGFuZCBwZXJzb25hbCByZWxhdGlvbnNoaXBzLCBhcmUgaW5jcmVhc2luZ2x5IGltcG9ydGFudCBpbiBkZXRlcm1pbmluZyBvdmVyYWxsIGhhcHBpbmVzcy4NCg0KKiBfX0RlbW9ncmFwaGljcyBhbmQgSGFwcGluZXNzX186IEluIG15IGFuYWx5c2lzLCBJIGRpZCBub3QgZGVsdmUgZGVlcGx5IGludG8gdGhlIGRldGFpbGVkIGNvcnJlbGF0aW9uIGJldHdlZW4gZGVtb2dyYXBoaWMgZmFjdG9ycyBhbmQgY29tbXV0aW5nIGJlaGF2aW9ycy4gSG93ZXZlciwgYmFzZWQgb24gdGhlIGNvbmR1Y3RlZCByZXNlYXJjaCBhbmQgdGhlIGNvbXBhcmlzb24gb2YgdGhlIGdlbmVyYXRlZCBncmFwaHMsIGl0IGlzIHBvc3NpYmxlIHRvIGRyYXcgc29tZSBpbnNpZ2h0cy4gVGhlIGZpbmRpbmdzIHN1Z2dlc3QgdGhhdCBkZW1vZ3JhcGhpYyBmYWN0b3JzIHN1Y2ggYXMgYWdlLCBnZW5kZXIsIGFuZCBtYXJpdGFsIHN0YXR1cyBkbyBwbGF5IGEgcm9sZSBpbiBzaGFwaW5nIGNvbW11dGluZyBiZWhhdmlvcnMgYW5kIHRoZWlyIGltcGFjdCBvbiBoYXBwaW5lc3MuIFNwZWNpZmljYWxseSwgeW91bmdlciByZXNwb25kZW50cywgcGFydGljdWxhcmx5IHRob3NlIGZyb20gbW9yZSByZWNlbnQgZGF0YSwgcmVwb3J0ZWQgaGlnaGVyIGxpZmUgc2F0aXNmYWN0aW9uIGRlc3BpdGUgdmFyaWF0aW9ucyBpbiBjb21tdXRpbmcgdGltZXMsIHdoaWNoIG1heSByZWZsZWN0IGdyZWF0ZXIgYWRhcHRhYmlsaXR5IG9yIHJlc2lsaWVuY2UuIEFkZGl0aW9uYWxseSwgbWFycmllZCBpbmRpdmlkdWFscywgd2hvIGdlbmVyYWxseSBoYXZlIHNob3J0ZXIgY29tbXV0ZXMgY29tcGFyZWQgdG8gc2luZ2xlIGluZGl2aWR1YWxzLCB0ZW5kIHRvIHJlcG9ydCBoaWdoZXIgbGV2ZWxzIG9mIGhhcHBpbmVzcy4gVGhpcyB1bmRlcnNjb3JlcyB0aGUgaW5mbHVlbmNlIG9mIHNvY2lhbCBzdXBwb3J0IHN5c3RlbXMgb24gb3ZlcmFsbCB3ZWxsLWJlaW5nLg0KDQpBbGwgZmFjdG9ycyBleGFtaW5lZCBpbiB0aGlzIHN0dWR54oCUZGVtb2dyYXBoaWNzLCBpbmNvbWUsIGVkdWNhdGlvbiwgZW1wbG95bWVudCwgYW5kIGNvbW11dGluZ+KAlGFyZSBpbnRlcmNvbm5lY3RlZCBpbiB0aGVpciBpbmZsdWVuY2Ugb24gaGFwcGluZXNzLiBEZW1vZ3JhcGhpY3Mgc2hhcGUgY29tbXV0aW5nIGJlaGF2aW9ycyBhbmQgcHJlZmVyZW5jZXMsIHdoaWNoLCBpbiB0dXJuLCBhZmZlY3QgbGlmZSBzYXRpc2ZhY3Rpb24uIEluY29tZSBhbmQgZWR1Y2F0aW9uIG5vdCBvbmx5IGRldGVybWluZSB0aGUgcXVhbGl0eSBvZiBlbXBsb3ltZW50IGJ1dCBhbHNvIGluZmx1ZW5jZSB0aGUgY2hvaWNlIG9mIGNvbW11dGluZyBtZXRob2RzIGFuZCBkaXN0YW5jZXMuIEVtcGxveW1lbnQgc3RhdHVzIGRpcmVjdGx5IGFmZmVjdHMgY29tbXV0aW5nIHBhdHRlcm5zLCBhcyBmdWxsLXRpbWUgYW5kIHN0YWJsZSBqb2JzIG1heSByZXF1aXJlIGxvbmdlciBjb21tdXRlcywgd2hpbGUgZmxleGlibGUgb3IgcmVtb3RlIGpvYnMgbWF5IHJlZHVjZSB0aGUgbmVlZCBmb3IgY29tbXV0aW5nIGFsdG9nZXRoZXIuDQoNCg0KIyBBcHBlbmRpeA0KDQojIyMgVmFyaWFibGVzwrQgbmFtZXMNCg0KIF9fcGVxdWl2LmR0YV9fDQoNCmQxMTEwMTogQWdlDQoNCmQxMTEwMmxsOiBHZW5kZXINCg0KZDExMTA0OiBNYXJpdGFsIFN0YXR1cw0KDQpkMTExMDY6IE51bWJlciBvZiBwZXJzb25zIGluIEhIDQoNCmQxMTEwOTogTnVtYmVyIG9mIFllYXJzIG9mIEVkdWNhdGlvbg0KDQpkMTExMDg6IEVkdWNhdGlvbiBXaXRoIFJlc3BlY3QgdG8gSGlnaCBTY2hvb2wNCg0KX19wZ2VuLmR0YV9fDQoNCnBnZW1wbHN0OiBFbXBsb3ltZW50IFN0YXR1cw0KDQogX19wbC5kdGFfXw0KDQpwbGgwMTc1OiBISCBpbmNvbWUgc2F0aXNmYWN0aW9uDQoNCnBsYjA1OTA6IERpc3RhbmNlIDEuIER3ZWxsaW5nIC0gMi4gRHdlbGxpbmcNCg0KcGxiMDU5MTogQ29tbXV0aW5nIEZyZXF1ZW5jeQ0KDQpwbGIwNTkyOiBDb21tdXRpbmcgVGltZSAoTWludXRlcykNCg0KIF9faGdlbi5kdGFfXw0KDQpoZ2hpbmM6IE1vbnRobHkgSEggaW5jb21lDQoNCiMgUmVmZXJlbmNlcw==